Skip to content

Commit c0c439d

Browse files
Render base64 images in threads (#601)
1 parent 7a6b66c commit c0c439d

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

app/MindWork AI Studio/Chat/ContentBlockComponent.razor

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,21 @@
107107
break;
108108

109109
case ContentType.IMAGE:
110-
if (this.Content is ContentImage { SourceType: ContentImageSource.URL or ContentImageSource.LOCAL_PATH } imageContent)
110+
if (this.Content is ContentImage imageContent)
111111
{
112-
<MudImage Src="@imageContent.Source"/>
112+
var imageSrc = imageContent.SourceType switch
113+
{
114+
ContentImageSource.BASE64 => ImageHelpers.ToDataUrl(imageContent.Source),
115+
ContentImageSource.URL => imageContent.Source,
116+
ContentImageSource.LOCAL_PATH => imageContent.Source,
117+
118+
_ => string.Empty
119+
};
120+
121+
if (!string.IsNullOrWhiteSpace(imageSrc))
122+
{
123+
<MudImage Src="@imageSrc" />
124+
}
113125
}
114126

115127
break;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
namespace AIStudio.Tools;
2+
3+
/// <summary>
4+
/// Helper methods for image handling, particularly for Base64 images.
5+
/// </summary>
6+
public static class ImageHelpers
7+
{
8+
/// <summary>
9+
/// Detects the MIME type of an image from its Base64-encoded header.
10+
/// </summary>
11+
/// <param name="base64ImageString">The Base64-encoded image string.</param>
12+
/// <returns>The detected MIME type (e.g., "image/png", "image/jpeg").</returns>
13+
public static string DetectMimeType(ReadOnlySpan<char> base64ImageString)
14+
{
15+
if (base64ImageString.IsWhiteSpace() || base64ImageString.Length < 10)
16+
return "image"; // Fallback
17+
18+
var header = base64ImageString[..Math.Min(20, base64ImageString.Length)];
19+
20+
//
21+
// See https://en.wikipedia.org/wiki/List_of_file_signatures
22+
//
23+
24+
// PNG: iVBORw0KGgo
25+
if (header.StartsWith("iVBORw0KGgo", StringComparison.Ordinal))
26+
return "image/png";
27+
28+
// JPEG: /9j/
29+
if (header.StartsWith("/9j/", StringComparison.Ordinal))
30+
return "image/jpeg";
31+
32+
// GIF: R0lGOD
33+
if (header.StartsWith("R0lGOD", StringComparison.Ordinal))
34+
return "image/gif";
35+
36+
// WebP: UklGR
37+
if (header.StartsWith("UklGR", StringComparison.Ordinal))
38+
return "image/webp";
39+
40+
// BMP: Qk
41+
if (header.StartsWith("Qk", StringComparison.Ordinal))
42+
return "image/bmp";
43+
44+
// Default fallback:
45+
return "image";
46+
}
47+
48+
/// <summary>
49+
/// Converts a Base64 string to a data URL suitable for use in HTML img src attributes.
50+
/// </summary>
51+
/// <param name="base64String">The Base64-encoded image string.</param>
52+
/// <param name="mimeType">Optional MIME type. If not provided, it will be auto-detected.</param>
53+
/// <returns>A data URL in the format "data:image/type;base64,..."</returns>
54+
public static string ToDataUrl(string base64String, string? mimeType = null)
55+
{
56+
if (string.IsNullOrEmpty(base64String))
57+
return string.Empty;
58+
59+
var detectedMimeType = mimeType ?? DetectMimeType(base64String);
60+
return $"data:{detectedMimeType};base64,{base64String}";
61+
}
62+
}

0 commit comments

Comments
 (0)