3b01efd8a6
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
62 lines
1.9 KiB
C#
62 lines
1.9 KiB
C#
using ImageMagick;
|
|
|
|
namespace MoneyMap.Services
|
|
{
|
|
/// <summary>
|
|
/// Service for converting PDF files to images for AI processing.
|
|
/// </summary>
|
|
public interface IPdfToImageConverter
|
|
{
|
|
/// <summary>
|
|
/// Converts the first page of a PDF to a base64-encoded PNG image.
|
|
/// </summary>
|
|
Task<string> ConvertFirstPageToBase64Async(string pdfPath);
|
|
|
|
/// <summary>
|
|
/// Converts PDF bytes to a base64-encoded PNG image.
|
|
/// </summary>
|
|
Task<string> ConvertFirstPageToBase64Async(byte[] pdfBytes);
|
|
}
|
|
|
|
public class PdfToImageConverter : IPdfToImageConverter
|
|
{
|
|
private const int DefaultDpi = 220;
|
|
|
|
public Task<string> ConvertFirstPageToBase64Async(string pdfPath)
|
|
{
|
|
var pdfBytes = File.ReadAllBytes(pdfPath);
|
|
return ConvertFirstPageToBase64Async(pdfBytes);
|
|
}
|
|
|
|
public Task<string> 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);
|
|
});
|
|
}
|
|
}
|
|
}
|