using Docnet.Core; using Docnet.Core.Models; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; public class ImagePreprocessor { // US Letter at 300 DPI — sufficient for Tesseract on clinical scans. private const int PdfRenderWidth = 2550; private const int PdfRenderHeight = 3300; public Stream Preprocess(Stream input, string contentType) { Stream? pdfRenderStream = null; try { if (contentType == "application/pdf") { pdfRenderStream = RenderPdfFirstPage(input); input = pdfRenderStream; } using var image = Image.Load(input); image.Mutate(ctx => ctx .Grayscale() .GaussianSharpen(1.5f) .BinaryThreshold(0.5f)); var output = new MemoryStream(); image.SaveAsPng(output); output.Position = 0; return output; } finally { pdfRenderStream?.Dispose(); } } private static Stream RenderPdfFirstPage(Stream pdfStream) { using var buffer = new MemoryStream(); pdfStream.CopyTo(buffer); var pdfBytes = buffer.ToArray(); using var docReader = DocLib.Instance.GetDocReader( pdfBytes, new PageDimensions(PdfRenderWidth, PdfRenderHeight)); if (docReader.GetPageCount() == 0) throw new InvalidOperationException("PDF contains no pages."); using var pageReader = docReader.GetPageReader(0); var rawBytes = pageReader.GetImage(); var width = pageReader.GetPageWidth(); var height = pageReader.GetPageHeight(); using var image = Image.LoadPixelData(rawBytes, width, height); var output = new MemoryStream(); image.SaveAsPng(output); output.Position = 0; return output; } }