diff --git a/app/MindWork AI Studio/Chat/ContentImage.cs b/app/MindWork AI Studio/Chat/ContentImage.cs index 997e9987..9f09e87c 100644 --- a/app/MindWork AI Studio/Chat/ContentImage.cs +++ b/app/MindWork AI Studio/Chat/ContentImage.cs @@ -7,7 +7,7 @@ namespace AIStudio.Chat; /// /// Represents an image inside the chat. /// -public sealed class ContentImage : IContent +public sealed class ContentImage : IContent, IImageSource { #region Implementation of IContent @@ -47,62 +47,4 @@ public sealed class ContentImage : IContent /// The image source. /// public required string Source { get; set; } - - /// - /// Read the image content as a base64 string. - /// - /// - /// The images are directly converted to base64 strings. The maximum - /// size of the image is around 10 MB. If the image is larger, the method - /// returns an empty string. - /// - /// As of now, this method does no sort of image processing. LLMs usually - /// do not work with arbitrary image sizes. In the future, we might have - /// to resize the images before sending them to the model. - /// - /// The cancellation token. - /// The image content as a base64 string; might be empty. - public async Task AsBase64(CancellationToken token = default) - { - switch (this.SourceType) - { - case ContentImageSource.BASE64: - return this.Source; - - case ContentImageSource.URL: - { - using var httpClient = new HttpClient(); - using var response = await httpClient.GetAsync(this.Source, HttpCompletionOption.ResponseHeadersRead, token); - if(response.IsSuccessStatusCode) - { - // Read the length of the content: - var lengthBytes = response.Content.Headers.ContentLength; - if(lengthBytes > 10_000_000) - return string.Empty; - - var bytes = await response.Content.ReadAsByteArrayAsync(token); - return Convert.ToBase64String(bytes); - } - - return string.Empty; - } - - case ContentImageSource.LOCAL_PATH: - if(File.Exists(this.Source)) - { - // Read the content length: - var length = new FileInfo(this.Source).Length; - if(length > 10_000_000) - return string.Empty; - - var bytes = await File.ReadAllBytesAsync(this.Source, token); - return Convert.ToBase64String(bytes); - } - - return string.Empty; - - default: - return string.Empty; - } - } } \ No newline at end of file diff --git a/app/MindWork AI Studio/Chat/IImageSource.cs b/app/MindWork AI Studio/Chat/IImageSource.cs new file mode 100644 index 00000000..1931630f --- /dev/null +++ b/app/MindWork AI Studio/Chat/IImageSource.cs @@ -0,0 +1,17 @@ +namespace AIStudio.Chat; + +public interface IImageSource +{ + /// + /// The type of the image source. + /// + /// + /// Is the image source a URL, a local file path, a base64 string, etc.? + /// + public ContentImageSource SourceType { get; init; } + + /// + /// The image source. + /// + public string Source { get; set; } +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Chat/IImageSourceExtensions.cs b/app/MindWork AI Studio/Chat/IImageSourceExtensions.cs new file mode 100644 index 00000000..836df531 --- /dev/null +++ b/app/MindWork AI Studio/Chat/IImageSourceExtensions.cs @@ -0,0 +1,63 @@ +namespace AIStudio.Chat; + +public static class IImageSourceExtensions +{ + /// + /// Read the image content as a base64 string. + /// + /// + /// The images are directly converted to base64 strings. The maximum + /// size of the image is around 10 MB. If the image is larger, the method + /// returns an empty string. + /// + /// As of now, this method does no sort of image processing. LLMs usually + /// do not work with arbitrary image sizes. In the future, we might have + /// to resize the images before sending them to the model. + /// + /// The image source. + /// The cancellation token. + /// The image content as a base64 string; might be empty. + public static async Task AsBase64(this IImageSource image, CancellationToken token = default) + { + switch (image.SourceType) + { + case ContentImageSource.BASE64: + return image.Source; + + case ContentImageSource.URL: + { + using var httpClient = new HttpClient(); + using var response = await httpClient.GetAsync(image.Source, HttpCompletionOption.ResponseHeadersRead, token); + if(response.IsSuccessStatusCode) + { + // Read the length of the content: + var lengthBytes = response.Content.Headers.ContentLength; + if(lengthBytes > 10_000_000) + return string.Empty; + + var bytes = await response.Content.ReadAsByteArrayAsync(token); + return Convert.ToBase64String(bytes); + } + + return string.Empty; + } + + case ContentImageSource.LOCAL_PATH: + if(File.Exists(image.Source)) + { + // Read the content length: + var length = new FileInfo(image.Source).Length; + if(length > 10_000_000) + return string.Empty; + + var bytes = await File.ReadAllBytesAsync(image.Source, token); + return Convert.ToBase64String(bytes); + } + + return string.Empty; + + default: + return string.Empty; + } + } +} \ No newline at end of file