推荐使用pdfiumsharp+skiasharp直接渲染pdf为位图:需初始化pdfium、校验加密与页有效性、正确部署native库、用sksurface缩放控制dpi、区分png白底/jpg压缩输出,并妥善dispose资源。

用 SkiaSharp + PDFiumSharp 直接渲染,别碰 iTextSharp 或 Ghostscript
PDF 转图本质是「渲染页面为位图」,不是解析文本。用文档处理库(比如 iTextSharp)或外部命令行工具(比如 Ghostscript)容易卡在字体缺失、权限限制、跨平台部署失败上。推荐组合:PDFiumSharp(基于 Google PDFium 的 .NET 封装,免依赖、支持 Windows/macOS/Linux)+ SkiaSharp(高性能绘图,输出质量可控)。
常见错误现象:System.DllNotFoundException: libpdfium.dll(没放对 native 库)、NullReferenceException 在 RenderPage(PDF 页为空或加密)、输出图片全黑(没调 canvas.Flush() 或 Alpha 通道没处理)。
- 必须安装两个 NuGet 包:
PDFiumSharp和SkiaSharp(v2.88+,旧版有 SkSurface 创建失败问题) -
PDFiumSharp初始化前需调用PDFium.Initialize(),且只能调一次;建议放在Main()或静态构造函数里 - 每页渲染前检查
page.Width > 0 && page.Height > 0,有些 PDF 第一页是空的(尤其扫描件 OCR 后产物) - 分辨率控制靠缩放:用
scale = dpi / 72f(PDF 默认 72 DPI),别直接设大宽高——否则内存爆炸
RenderPage 输出 PNG/JPG 的关键参数和 Alpha 处理
PDF 内容可能带透明度(如阴影、渐变),但 JPG 不支持 Alpha。直接保存为 JPG 会留黑底,PNG 则默认保留透明通道——但多数场景要白底。
使用场景:导出给前端预览(要白底 PNG)、生成报告缩略图(JPG 压缩率优先)、OCR 前处理(灰度 + 白底最稳)。
- 输出白底 PNG:
using var surface = SKSurface.Create(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Premul);→ 清屏:canvas.Clear(SKColors.White) - 输出 JPG:
image.Encode(SKEncodedImageFormat.Jpeg, 90),质量 90 是平衡点,低于 75 文字边缘易出现块状模糊 - 避免内存泄漏:每个
SKSurface、SKImage、SKData都必须Dispose(),用using块最安全 - 不要用
SKBitmap中转——它不支持高 DPI 缩放,直接SKSurface+Canvas渲染更准
处理加密 PDF 和异常页(IsEncrypted、GetPageCount 必须前置校验)
很多生产环境 PDF 带密码(即使空密码也算加密),PDFiumSharp 不会自动解密,OpenDocument 会静默失败返回 null,后续调用直接崩。
性能影响:跳过加密页比硬解更快;兼容性上,PDFium 支持 AES-128/AES-256,但不支持 RC4(已淘汰,但老 PDF 还有)。
- 打开前先读头:
if (PDFium.IsEncrypted(filePath)) { throw new InvalidOperationException("PDF is encrypted"); } -
GetPageCount()必须在OpenDocument成功后立刻调,不能等循环到某页才查——有些损坏 PDF 会在中间页崩掉计数 - 页索引从 0 开始,但
document.GetPage(0)可能返回 null(尤其第一页是注释页),加!= null判断再渲染 - 遇到坏页跳过并记录日志:
Console.WriteLine($"Skip broken page {i} in {filePath}");,别让整个批量任务停摆
Windows 下 libpdfium.dll 找不到?三个位置必须检查
不是所有项目都能自动复制 native 库。PDFiumSharp 依赖 libpdfium.dll(Windows)、libpdfium.dylib(macOS)、libpdfium.so(Linux),NuGet 不负责部署它们到输出目录。
容易踩的坑:本地调试 OK,发布到 IIS 或 Linux Docker 就报 DLL not found;或者 x64 项目引用了 x86 的 dll。
- 确认项目平台目标:x64 项目必须用 x64 版
libpdfium.dll(官方 GitHub Release 页分 arch 提供) - 把 dll 放进项目根目录,属性设为「始终复制」,并在
.csproj里加:<content include="libpdfium.dll" copytooutputdirectory="PreserveNewest"></content> - ASP.NET Core 发布时,若用
dotnet publish -r win-x64,需手动把对应 runtime 的 dll 放入publish/目录,否则bin/下没有 - 用
Process Monitor(Sysinternals)抓LoadLibrary调用路径,比猜“是不是路径不对”快十倍
最麻烦的其实是字体回退——PDF 指定了“SimSun”,但 Linux 容器没装中文字体,结果中文全成方框。这得提前用 SkiaSharp 注册备用字体,不是 PDF 渲染层能绕开的。










