使用 pdf.js 在 Node.js 中将 PDF 首页转换为 PNG 图片:pdf2png 示例实战指南

发布时间:2026/11/5 11:49:05

使用 pdf.js 在 Node.js 中将 PDF 首页转换为 PNG 图片:pdf2png 示例实战指南 使用 pdf.js 在 Node.js 中将 PDF 首页转换为 PNG 图片pdf2png 示例实战指南【免费下载链接】pdf.jsPDF Reader in JavaScript项目地址: https://gitcode.com/gh_mirrors/pd/pdf.js导读本文基于 pdf.js 仓库中的官方 Node.js 示例 examples/node/pdf2png/README.md 及其核心实现 pdf2png.mjs完整讲解如何在纯 Node.js 环境下加载 PDF 文档、渲染页面到 Canvas并输出为 PNG 图片文件。读完本文你将掌握 pdf.js 在服务端无浏览器 DOM环境下的完整工作链路从gulp dist-install构建本地 npm 包到getDocument加载文档、page.getViewport计算视口、canvasFactory创建画布、page.render绘制页面最后用canvas.toBuffer(image/png)落盘成图。一、示例概览它解决什么问题pdf2png是 pdf.js 提供的官方示例之一其 README 开篇即说明目标Example to demonstrate converting a PDF file to a PNG image using the PDF.js library.即演示如何使用 pdf.js 库把 PDF 文件转换为 PNG 图片。具体而言该示例会从命令行参数或默认路径读取一个 PDF 文件加载文档并取出第一页以 100% 缩放比例在 Node 侧的 Canvas 上渲染该页将画布内容编码为 PNG 二进制数据并写入output.png释放页面资源page.cleanup()。与仓库中其他 Node 示例形成互补同目录下的 getinfo.mjs 演示元数据与文本内容抽取examples/text-only/pdf2svg.mjs 演示在浏览器端把文本内容转成 SVG而pdf2png则聚焦于像素级栅格化输出是服务端截图、预览图生成、文档转图片等场景的最小可运行模板。二、运行环境与前置准备2.1 环境要求从仓库根目录 package.json 可以确认本项目为 ES Moduletype: module且 Node.js 引擎要求为22.13.0 || 24。因此运行示例前请确保Node.js 版本 ≥ 22.13.0或 ≥ 24已安装项目依赖npm 会自动安装pdfjs-dist、gulp 等已构建 pdf.js 发行包。2.2 安装依赖并构建 pdf.js 库README 给出了两条初始化命令$ npm install $ gulp dist-installnpm install安装仓库根目录的依赖包括 gulp 构建工具链与运行时所需的pdfjs-dist等 npm 包。gulp dist-install这是 pdf.js 仓库的**自举bootstrap**步骤。查看 gulpfile.mjs 中dist-install任务的定义gulpfile.mjs 第 3493–3502 行附近可以看到dist-install, gulp.series(dist, function createDistInstall(done) { let distPath DIST_DIR; // 计算相对路径后…… safeSpawnSync(npm, [install, distPath], opts);它先执行dist任务构建build/dist/目录下的 pdf.js 发行产物包括pdf.mjs、pdf.worker.mjs、cmaps/、standard_fonts/等资源再把构建结果作为一个本地 npm 包安装到项目的node_modules中。这一步是示例代码中import { getDocument } from pdfjs-dist/legacy/build/pdf.mjs能够解析的前提务必在运行示例前完成。三、运行示例把 PDF 第一页转成 PNGREADME 给出运行命令$ cd examples/node/pdf2png $ node pdf2png.mjs执行后会在当前目录examples/node/pdf2png/生成output.png控制台输出类似# PDF document loaded. Finished converting first page of PDF file to a PNG image.3.1 如何指定自己的 PDF 文件示例实现 pdf2png.mjs 支持把目标 PDF 路径作为第一个命令行参数传入第 28–29 行const pdfPath process.argv[2] || ../../../web/compressed.tracemonkey-pldi-09.pdf;因此可以这样转换任意本地 PDF$ node pdf2png.mjs /path/to/your/document.pdf若不传参数则默认使用仓库自带的 web/compressed.tracemonkey-pldi-09.pdfpdf.js 官方示例常用的测试文档文件内容以Uint8Array形式读入内存const data new Uint8Array(fs.readFileSync(pdfPath));四、源码逐段精讲pdf2png.mjs 的完整工作流下面按 pdf2png.mjs 的执行顺序拆解每一段代码的作用。4.1 导入与资源路径配置import fs from fs; import { getDocument } from pdfjs-dist/legacy/build/pdf.mjs; // Some PDFs need external cmaps. const CMAP_URL ../../../node_modules/pdfjs-dist/cmaps/; const CMAP_PACKED true; // Where the standard fonts are located. const STANDARD_FONT_DATA_URL ../../../node_modules/pdfjs-dist/standard_fonts/;几个要点导入的是pdfjs-dist/legacy/build/pdf.mjs即legacy 构建它不依赖现代浏览器私有特性更适合 Node.js 服务端环境cMapUrl部分 PDF 使用 CJK 等编码需要外部字符映射表cmap。该路径指向gulp dist-install安装到node_modules的pdfjs-dist/cmaps/目录cMapPacked: true告知 pdf.js 使用.bcmap压缩格式的 cmap 文件仓库 external/bcmaps 中即存放这些.bcmap资源standardFontDataUrl指向标准 14 字体数据如 external/standard_fonts 中的 Foxit/Liberation 字体用于 PDF 内置标准字体的替换渲染。4.2 加载文档getDocumentconst loadingTask getDocument({ data, cMapUrl: CMAP_URL, cMapPacked: CMAP_PACKED, standardFontDataUrl: STANDARD_FONT_DATA_URL, }); try { const pdfDocument await loadingTask.promise; console.log(# PDF document loaded.);getDocument返回一个loadingTask其.promise在文档解析完成后 resolve 为PDFDocumentProxy这里以内存data字节流方式加载同样的 API 也支持{ url }方式参见 getinfo.mjs 中的getDocument({ url: pdfPath })cmap 与标准字体配置属于可选项但强烈建议缺少时中文等复杂编码 PDF 可能渲染出乱码或空白。4.3 获取页面与视口viewportconst page await pdfDocument.getPage(1); const viewport page.getViewport({ scale: 1.0 });getPage(1)取出第一页页码从 1 开始getViewport({ scale: 1.0 })以 100% 缩放计算页面可见区域返回包含width、height、transform等信息的视口对象。调整scale如1.5、2.0即可控制输出图片的分辨率这是实现PDF 转高清 PNG最直接的旋钮。4.4 创建 Node CanvascanvasFactoryconst canvasFactory pdfDocument.canvasFactory; const canvasAndContext canvasFactory.create( viewport.width, viewport.height ); const renderContext { canvasContext: canvasAndContext.context, viewport, };在浏览器环境中pdf.js 渲染依赖 DOMcanvas而在 Node 环境中没有 DOM因此 pdf.js 在服务端构建中提供canvasFactory——一个负责创建/回收画布的工厂对象pdfDocument.canvasFactory由pdfjs-dist的 Node 入口在初始化时注入基于node-canvas实现因此无需手动 new CanvascanvasFactory.create(width, height)返回{ canvas, context }其中canvas是 Node Canvas 实例context是 2D 绘图上下文。这一机制贯穿整个渲染管线在 src/display/canvas.js 中栅格化器内部通过this.canvasFactory.create(...)大量分配临时画布例如透明遮罩 smask、裁剪与缩放缓冲区并在用完后由this.canvasFactory.destroy(...)回收见 canvas.js 中create/destroy/reset的众多调用点。理解这一点有助于解释为什么服务端渲染必须显式传入可用的canvasFactory也说明示例代码中直接使用pdfDocument.canvasFactory是一种简洁且正确的做法。4.5 渲染页面并输出 PNGconst renderTask page.render(renderContext); await renderTask.promise; // Convert the canvas to an image buffer. const image canvasAndContext.canvas.toBuffer(image/png); fs.writeFile(output.png, image, function (error) { if (error) { console.error(Error: error); } else { console.log(Finished converting first page of PDF file to a PNG image.); } }); // Release page resources. page.cleanup();page.render(renderContext)返回一个renderTask其promise在绘制完成时 resolve——必须await之后再取画布内容否则拿到的还是空白画布canvas.toBuffer(image/png)是 Node Canvas 提供的编码接口将画布像素编码为 PNG 的Bufferfs.writeFile将其写入output.png写入路径相对于当前工作目录examples/node/pdf2png/page.cleanup()释放页面级资源字体、图像缓存等避免长时间运行的服务内存膨胀更完整的生命周期管理还应像 getinfo.mjs 那样在结束时调用loadingTask.destroy()销毁整个文档对象try/catch包裹主流程加载或渲染失败时打印reason便于排查。五、核心 API 速查表环节API作用对应源码位置加载文档getDocument({ data, cMapUrl, cMapPacked, standardFontDataUrl })创建加载任务解析 PDFpdf2png.mjs 第 33–38 行等待解析loadingTask.promiseresolve 为PDFDocumentProxy同上第 41 行取页pdfDocument.getPage(1)获取第 1 页从 1 计数第 44 行视口page.getViewport({ scale: 1.0 })计算页面尺寸与变换控制分辨率第 47 行建画布pdfDocument.canvasFactory.create(w, h)Node 环境下创建画布与 2D 上下文第 46–51 行渲染page.render(renderContext)→renderTask.promise把页面绘制进画布第 57–58 行编码输出canvas.toBuffer(image/png)fs.writeFile生成 PNG 文件第 60–67 行资源释放page.cleanup()/loadingTask.destroy()释放页面/文档资源第 69 行 / getinfo.mjs 第 54 行六、常见问题与调优建议Cannot find module pdfjs-dist/legacy/build/pdf.mjs说明尚未执行gulp dist-install先在仓库根目录运行npm install与gulp dist-install把本地构建产物安装进node_modules。中文/日文等 PDF 乱码检查cMapUrl、cMapPacked、standardFontDataUrl三个配置是否指向有效的pdfjs-dist资源目录仓库中对应的原始资源位于 external/bcmaps 与 external/standard_fonts构建时会随dist任务复制进发行包。输出图片模糊调大getViewport({ scale })的scale值例如2.0可得到 2 倍像素密度输出相应地画布尺寸与渲染耗时、内存占用都会增大。转换多页 PDF在pdfDocument.numPages范围内循环getPage(i)并逐页渲染即可把输出文件名与页码关联如output-${i}.png。内存与资源长时间批量转换时每页渲染完调用page.cleanup()全部结束后调用loadingTask.destroy()并配合canvasFactory.destroy(canvasAndContext)归还画布对象。七、小结pdf2png示例用不到 70 行代码展示了 pdf.js 在 Node.js 环境下PDF → PNG的完整链路其核心价值在于揭示了canvasFactory 抽象——pdf.js 通过工厂模式把画布创建与栅格化解耦从而让同一套渲染内核同时运行在浏览器 DOM 与 Node 服务端给出了cmap / 标准字体等资源路径配置的最佳实践这是服务端渲染中文等复杂 PDF 的关键提供了一个可复制的模板修改scale控制分辨率、循环页码实现批量转换、接入canvasFactory.destroy与loadingTask.destroy完善资源回收即可扩展为生产级的文档转图片服务。如需进一步探索可对照阅读同仓库的 examples/node/getinfo.mjs元数据与文本抽取和 examples/text-only/pdf2svg.mjs文本转 SVG以及渲染内核实现 src/display/canvas.js从而全面掌握 pdf.js 的文档处理能力。【免费下载链接】pdf.jsPDF Reader in JavaScript项目地址: https://gitcode.com/gh_mirrors/pd/pdf.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/4 20:15:35

单片机毕设项目:基于 STM32 或 51 单片机的自动降温婴儿床智能控制系统设计 基于 STM32 或 51 单片机的居家婴幼儿安全监护硬件平台设计(025407)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/11/5 11:39:15

PostgreSQL数据类型选择指南与性能优化实践

1. PostgreSQL数据类型概述PostgreSQL作为一款功能强大的开源关系型数据库,其数据类型系统之丰富远超大多数同类产品。我在实际项目中最常遇到的问题是:面对十几种数字类型、多种字符串类型以及各种特殊类型时,开发团队往往凭直觉选择&#x…

2026/11/5 11:34:12

Simulink S-function执行时序与状态管理原理详解

简介:本资源是面向MATLAB/Simulink初学者与控制系统建模学习者的S-Function入门实践包,聚焦自定义系统函数开发这一核心能力,解决标准库无法覆盖的特定数学运算与动态逻辑建模需求。压缩包共4个文件(2个M文件实现核心算法逻辑&…

2026/11/5 11:34:12

低空经济三维智能感知与实时调度技术解析

1. 低空经济三维空间智能感知与管控体系概述低空经济作为新兴经济形态,正在全球范围内快速发展。根据国际航空运输协会(IATA)预测,到2030年,全球城市空中交通市场规模将达到1.5万亿美元。在这一背景下,《低…

2026/11/5 11:34:12

链表数据结构与PTA解题技巧详解

1. 链表基础与数据结构课程实践 链表作为线性表的链式存储结构,是数据结构课程中承前启后的关键内容。在山东理工大学(SDUT)的数据结构与算法课程体系中,链表章节通常安排在顺序表之后、树结构之前,这种教学顺序设计体…

2026/11/5 11:34:12

Simulink S-Function核心机制与两个经典C示例解析

简介:本资源是面向MATLAB/Simulink初学者与控制系统建模学习者的S-Function入门实践包,聚焦自定义系统函数开发这一核心能力,解决标准库无法覆盖的特定数学运算与动态逻辑建模需求。压缩包共4个文件(2个M文件实现核心算法逻辑&…

2026/11/5 11:34:12

Mantle系统架构:云存储局部性与扩展性的突破

1. 项目概述:Mantle系统架构演进的技术突围在云存储技术高度成熟的今天,百度沧海存储团队完成的Mantle系统设计堪称一次教科书级别的技术突围。这个被SOSP25收录的存储系统创新案例,完美诠释了如何在看似饱和的技术领域实现突破——不是通过堆…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 0:02:07

多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中…

2026/11/5 0:02:07

大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#…

2026/11/5 0:02:07

鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑