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