using ImageMagick; namespace MoneyMap.Services { /// /// Service for converting PDF files to images for AI processing. /// public interface IPdfToImageConverter { /// /// Converts the first page of a PDF to a base64-encoded PNG image. /// Task ConvertFirstPageToBase64Async(string pdfPath); /// /// Converts PDF bytes to a base64-encoded PNG image. /// Task ConvertFirstPageToBase64Async(byte[] pdfBytes); } public class PdfToImageConverter : IPdfToImageConverter { private const int DefaultDpi = 220; public Task ConvertFirstPageToBase64Async(string pdfPath) { var pdfBytes = File.ReadAllBytes(pdfPath); return ConvertFirstPageToBase64Async(pdfBytes); } public Task ConvertFirstPageToBase64Async(byte[] pdfBytes) { return Task.Run(() => { var settings = new MagickReadSettings { Density = new Density(DefaultDpi), BackgroundColor = MagickColors.White, ColorSpace = ColorSpace.sRGB }; using var pages = new MagickImageCollection(); pages.Read(pdfBytes, settings); if (pages.Count == 0) throw new InvalidOperationException("PDF has no pages"); using var img = (MagickImage)pages[0].Clone(); // Ensure we have a clean 8-bit RGB canvas img.ColorType = ColorType.TrueColor; img.Alpha(AlphaOption.Remove); // flatten onto white img.ResetPage(); // Convert to PNG bytes var imageBytes = img.ToByteArray(MagickFormat.Png); return Convert.ToBase64String(imageBytes); }); } } }