PDF 转图片

每一页渲染成一张图,DPI 想多高就多高。选中 DPI 时先把输出像素和内存算给你看,超了浏览器画布上限会直接拦住。

可以拖文件进来,全程在本机渲染,PDF 不会上传到任何服务器。

选择 PDF 后先看清单,再决定 DPI 和格式

关于 PDF 转图片

DPI 到底影响什么。PDF 是矢量的,页面上写着「这一行文字是 12 磅」,而不是「这一行有多少像素」。转图片时必须指定一个分辨率,这一步就是把矢量变成点阵。72 DPI 时 1 磅正好 1 像素,所以 12 磅的字只有 12 像素高,屏幕上看还行,一放大就糊;300 DPI 时同样的字有 50 像素高,放大也清晰。换算关系是「像素 = 磅 ÷ 72 × DPI」,A4 纸 595 × 842 磅,300 DPI 就是 2480 × 3508 像素。

为什么要限制 DPI 和页数。画布占的是浏览器内存里的连续空间,每个像素 4 个字节。一张 A4 在 300 DPI 下约 3480 万像素,就是 139 MB;600 DPI 直接变成 557 MB,再加上编码时的中间副本,标签页很容易被系统杀掉。所以这里在渲染前会算一遍像素总量,超了就提前拦住并提示降 DPI。单边 16384 像素是浏览器画布的硬上限,超了会得到空白图而不是报错,更隐蔽。

中文 PDF 可能缺字或变方框。转图片依赖 PDF 里嵌入的字体。如果文件没嵌字体,渲染时只能用系统字体替代,字形会有细微差异,个别生僻字可能变成方框或直接消失。这在转图片时比转文本好一些,因为至少保留了原始版面。遇到缺字可以试着换成原版 Acrobat 或 pdftoppm 这类工具,它们的字体回退策略更完整。

透明背景只对 PNG 和 WebP 有效。PDF 页面本身是白纸,所以导出的图默认铺白底。当页面有透明区域时,PNG 和 WebP 能保留透明,JPEG 不支持透明,透明部分会变成黑块,所以用 JPEG 输出时这里会先铺一层白底。想要透明背景就用 PNG。

要矢量图就别转图片。把 PDF 转成图片就丢掉了矢量特性,放大会糊。如果目的是插图(比如放进网页、放进文档里的示意图),可以先用 PDF 编辑器或 pdf-lib 把某一页拆成单页 PDF,再嵌入支持 PDF 的环境;或者用 Inkscape、pdftocairo 的 SVG 模式转成矢量图。浏览器里没有高质量的 PDF 转 SVG 方案,这里不做。

选 DPI 的几个经验值

做网页配图、聊天里发个预览,96 或 150 DPI 就够,再高只是让文件变大;要放进 PPT、Word 里打印,300 DPI 是印刷行业的标准起点;需要把整页放大约看细节,比如图纸和电路图,才值得上 600 DPI,而且建议一次只导一页。反过来,如果你的目标其实是「提取页面里的图」,转图片会先渲染整页再截取,画质取决于 PDF 里图片本身的压缩率,正确做法是用 qpdf 或 pdfimages 把内嵌图片原样抽出来。

为什么要单独加载解析模块。PDF 的解析和渲染由 pdf.js 完成,它带一份独立的后台线程脚本(worker)。这个脚本体积约一兆,只有在真正上传 PDF 时才会下载,进页面看说明不会付这份流量。worker 跑在后台线程里,所以解析几百页的文件时页面还能响应滚动和按钮,只是渲染每一页时主线程会短暂变忙。

文件不会离开这台电脑。整个解析、渲染、取字的过程都在浏览器本机进行,没有任何一步把文件发到服务器。断网之后这些工具照样能用(前提是页面已经打开、worker 已经加载过)。如果你在公司内网处理涉密文件,可以用浏览器开发者工具的网络面板自己确认:除了页面本身的静态资源,不会有任何上传请求。

大文件的实际限制。整个 PDF 会被读进内存再交给 pdf.js 解析,页数越多、里面的图片越多,占用越大。一百页以内的普通文档完全没问题;超过五百页或几百兆的扫描件,浏览器可能变卡甚至被系统杀掉标签页。这种情况更稳的做法是用命令行的 pdftotext、pdftoppm 或 qpdf 处理,它们没有浏览器的内存和画布上限。