You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6多页PDF转单张高清PNG/JPG转换器问题求助

多页PDF转单张高清OCR图片的文字错位问题解决

问题概述

需将多页PDF(如15页)转换为单张高清PNG/JPG用于OCR识别,现有基于Docnet的代码仅对常规PDF(如发票)有效,处理部分复杂PDF时出现文字错位、破损,内容无法识别。要求全程通过byte[]操作,不落地本地文件。

原代码核心问题

  1. Docnet渲染局限性:Docnet对含矢量字体、特殊布局或加密内容的复杂PDF渲染支持不足,易出现错位失真
  2. 字节拼接错误:手动拼接页面图像字节数组时存在字节对齐问题,直接导致图像数据损坏
  3. 低效图像操作:使用SetPixel逐像素处理,不仅效率低,还容易引入额外失真

推荐解决方案:基于PdfiumViewer实现

PdfiumViewer基于Google的Pdfium引擎,对复杂PDF的渲染准确性远优于Docnet,且原生支持.NET环境的内存流操作。

1. 安装依赖包

Install-Package PdfiumViewer

2. 实现转换代码

以下代码直接处理PDF字节数组,生成拼接后的高清JPG字节流:

using PdfiumViewer;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

public byte[] PdfToSingleHighResImage(byte[] pdfBytes)
{
    // 设置OCR最优分辨率:300DPI
    const int renderDpi = 300;
    
    using var pdfStream = new MemoryStream(pdfBytes);
    using var document = PdfDocument.Load(pdfStream);
    
    // 预计算拼接后图像的总尺寸
    int totalHeight = 0;
    int maxPageWidth = 0;
    var pageBitmaps = new List<Bitmap>();
    
    foreach (var page in document.Pages)
    {
        // 渲染单页为Bitmap
        var pageBitmap = page.Render(renderDpi, renderDpi, PdfRenderFlags.None);
        pageBitmaps.Add(pageBitmap);
        
        maxPageWidth = Math.Max(maxPageWidth, pageBitmap.Width);
        totalHeight += pageBitmap.Height;
    }
    
    // 创建拼接后的总图像画布
    using var combinedImage = new Bitmap(maxPageWidth, totalHeight, PixelFormat.Format32bppArgb);
    using var graphics = Graphics.FromImage(combinedImage);
    
    // 填充白色背景,避免透明区域干扰OCR识别
    graphics.FillRectangle(Brushes.White, 0, 0, maxPageWidth, totalHeight);
    
    // 逐页绘制到总画布
    int currentYOffset = 0;
    foreach (var bitmap in pageBitmaps)
    {
        graphics.DrawImage(bitmap, 0, currentYOffset);
        currentYOffset += bitmap.Height;
        bitmap.Dispose();
    }
    
    // 保存为高质量JPG(质量90兼顾清晰度与文件大小)
    using var outputStream = new MemoryStream();
    var jpgEncoder = GetImageEncoder(ImageFormat.Jpeg);
    var encoderParams = new EncoderParameters(1);
    encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
    
    combinedImage.Save(outputStream, jpgEncoder, encoderParams);
    return outputStream.ToArray();
}

// 辅助方法:获取指定格式的图像编码器
private ImageCodecInfo GetImageEncoder(ImageFormat format)
{
    foreach (var codec in ImageCodecInfo.GetImageDecoders())
    {
        if (codec.FormatID == format.Guid)
            return codec;
    }
    return null;
}

方案优势

  • 渲染准确性:Pdfium引擎对矢量内容、特殊字体、加密PDF的处理更可靠,彻底解决文字错位问题
  • 高效内存操作:全程通过MemoryStream处理,无需本地文件,符合需求
  • OCR友好:可自定义DPI(300DPI为OCR最优选择),保证识别精度
  • 简化逻辑:内置页面渲染与图像拼接逻辑,避免手动操作字节数组的错误

备选方案:Ghostscript.NET

若PdfiumViewer仍无法满足需求,可尝试基于Ghostscript的Ghostscript.NET,专业级PDF处理工具对极端复杂PDF的支持更完善:

Install-Package Ghostscript.NET

核心逻辑为通过Ghostscript将PDF直接转换为单张大图,再读取字节数组,具体实现可参考官方文档。

内容的提问来源于stack exchange,提问作者Kamil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:27:37