Fixed slide images reaching the AI as raw Base64 data

This commit is contained in:
Thorsten Sommer 2026-08-10 19:58:39 +02:00
parent ea5efca69d
commit e739468a85
Signed by untrusted user who does not match committer: tsommer
GPG Key ID: 371BBA77A02C0108
4 changed files with 43 additions and 17 deletions

View File

@ -132,7 +132,32 @@ public static class ContentStreamSseHandler
CHUNKED_IMAGES.Remove(id, out _); CHUNKED_IMAGES.Remove(id, out _);
return base64Image; return base64Image;
} }
/// <summary>
/// Assembles the collected segments of an image into a Markdown image.
/// </summary>
/// <remarks>
/// Handing the naked Base64 data to the AI says nothing: it is neither readable text nor an
/// image it could look at. Only the data URI makes it one, so every reader must embed its
/// images this way.
/// </remarks>
/// <param name="id">The ID of the image to assemble.</param>
/// <param name="mediaType">The media type the runtime reported, if any.</param>
/// <returns>The Markdown image, or null when no data was collected for that ID.</returns>
public static string? BuildImageMarkdown(string id, string? mediaType)
{
var base64Image = BuildImage(id);
if (string.IsNullOrWhiteSpace(base64Image))
return null;
//
// Both readers compress their images, and that compression produces JPEG. A runtime which
// does not report the media type therefore delivered JPEG as well.
//
var imageMediaType = string.IsNullOrWhiteSpace(mediaType) ? "image/jpeg" : mediaType;
return $"![Image](data:{imageMediaType};base64,{base64Image})";
}
public static string? Clear(string streamId) public static string? Clear(string streamId)
{ {
if (string.IsNullOrWhiteSpace(streamId)) if (string.IsNullOrWhiteSpace(streamId))

View File

@ -31,12 +31,11 @@ public sealed class DocumentManager
if (ContentStreamSseHandler.ProcessImageSegment(image.Id, image)) if (ContentStreamSseHandler.ProcessImageSegment(image.Id, image))
{ {
var base64 = ContentStreamSseHandler.BuildImage(image.Id); var markdownImage = ContentStreamSseHandler.BuildImageMarkdown(image.Id, image.MediaType);
if (!string.IsNullOrWhiteSpace(base64)) if (markdownImage is not null)
{ {
var mediaType = string.IsNullOrWhiteSpace(image.MediaType) ? "image/jpeg" : image.MediaType;
this.currentPageContent.AppendLine(); this.currentPageContent.AppendLine();
this.currentPageContent.AppendLine($"![Image](data:{mediaType};base64,{base64})"); this.currentPageContent.AppendLine(markdownImage);
} }
} }

View File

@ -1,8 +1,10 @@
using System.Text;
namespace AIStudio.Tools; namespace AIStudio.Tools;
public sealed class SlideImageContent(string base64Image) : ISlideContent /// <summary>
/// An image of a slide, ready to be appended to the slide's Markdown.
/// </summary>
/// <param name="markdownImage">The image as a Markdown image with an embedded data URI.</param>
public sealed class SlideImageContent(string markdownImage) : ISlideContent
{ {
public StringBuilder Base64Image => new(base64Image); public string MarkdownImage => markdownImage;
} }

View File

@ -52,11 +52,11 @@ public sealed class SlideManager
// //
if (addImage) if (addImage)
{ {
var img = ContentStreamSseHandler.BuildImage(image!.Id!); var markdownImage = ContentStreamSseHandler.BuildImageMarkdown(image!.Id!, image.MediaType);
var slideImage = new SlideImageContent(img); if (markdownImage is not null)
createdSlide.Content.Add(slideImage); createdSlide.Content.Add(new SlideImageContent(markdownImage));
} }
this.slides[slideNumber] = createdSlide; this.slides[slideNumber] = createdSlide;
} }
else else
@ -75,9 +75,9 @@ public sealed class SlideManager
// Add any image content? // Add any image content?
if (addImage) if (addImage)
{ {
var img = ContentStreamSseHandler.BuildImage(image!.Id!); var markdownImage = ContentStreamSseHandler.BuildImageMarkdown(image!.Id!, image.MediaType);
var slideImage = new SlideImageContent(img); if (markdownImage is not null)
slide.Content.Add(slideImage); slide.Content.Add(new SlideImageContent(markdownImage));
} }
} }
} }
@ -96,7 +96,7 @@ public sealed class SlideManager
foreach (var image in slide.Content.OfType<SlideImageContent>()) foreach (var image in slide.Content.OfType<SlideImageContent>())
{ {
content.AppendLine(image.Base64Image.ToString()); content.AppendLine(image.MarkdownImage);
content.AppendLine(); content.AppendLine();
} }
} }