OCRmyPDF 实战手册:从基础 OCR 到 v17 新特性的完整操作指南
本文为 OCRmyPDF 仓库自带 Cookbook 文档的成文版。围绕"一条命令加参数"这一核心工作方式,它系统覆盖了 OCRmyPDF 的日常用法:添加 OCR 层、选择输出类型(PDF / PDF/A / 无输出)、图像预处理(旋转、去背景、倾斜校正、清理)、非英语识别、sidecar 文本提取、--pages 页码级控制、--mode 处理模式,以及 v17 引入的光栅化器选择与无 Ghostscript 的 PDF/A 转换。读完本文,你可以针对具体扫描件任务组合出恰当的命令行参数,并理解每个参数在源码中的实际默认值与校验规则。
基础用法
OCRmyPDF 自带帮助,这是查询全部参数的第一入口:
ocrmypdf --help
添加 OCR 层并转换为 PDF/A
最典型的用法是把扫描件加上 OCR 文本层,默认输出 PDF/A(用于长期归档的标准 PDF 子集):
ocrmypdf input.pdf output.pdf
添加 OCR 层并输出标准 PDF
如果不需要 PDF/A 合规性,可用 --output-type pdf 输出普通 PDF:
ocrmypdf --output-type pdf input.pdf output.pdf
--output-type 在源码中被校验为 auto / pdfa / pdf / pdfa-1 / pdfa-2 / pdfa-3 / none 七个取值(见 OcrOptions.validate_output_type),其中 none 表示不产生 PDF 输出,常用于只提取 sidecar 文本的场景。
将彩色/灰度图像统一转成 JPEG 的 PDF/A
ocrmypdf --output-type pdfa --pdfa-image-compression jpeg input.pdf output.pdf
该参数属于 Ghostscript 选项组(pdfa_image_compression 字段定义于 src/ocrmypdf/_options.py),只在经 Ghostscript 产出 PDF/A 时生效。
用优化器降低 JPEG 质量
压缩输出中 JPEG 体积的推荐方式是使用优化器(optimizer),而不是去调 Ghostscript 自身的 JPEG 参数:
ocrmypdf --optimize 2 --jpeg-quality 60 input.pdf output.pdf
文档强调:优化器不依赖 --output-type,无论输出是普通 PDF 还是 Ghostscript 产出的 PDF/A 都会生效。从源码可以印证这一点:optimize() 函数中,若用户未显式指定 --jpeg-quality,会按优化等级自动补默认值——低于 -O3 时用内置的默认 JPEG 质量,-O3 时直接降到 40(见 src/ocrmypdf/optimize.py)。完整的优化等级说明见 docs/optimizer.md。
原地修改文件
ocrmypdf myfile.pdf myfile.pdf
输入输出同名即原地修改。文件只在 OCRmyPDF 成功完成后才会被覆盖,失败时原文件保持不动。
页面旋转校正
OCRmyPDF 会为每一页尝试自动纠正方向,这对混排了横版与竖版页面的扫描作业尤其有用:
ocrmypdf --rotate-pages myfile.pdf myfile.pdf
阈值参数 --rotate-pages-threshold 控制旋转的激进程度。它的含义是:OCR 引擎认为"应当改变方向"相对于"保持原样"的置信度比值。默认值比较保守——从源码看,默认阈值为 14.0(src/ocrmypdf/_defaults.py),且合法范围被校验器限制在 0 到 1000 之间(src/ocrmypdf/_options.py)。处理时,页面方向的置信度只有达到或超过该阈值才会真正执行旋转(src/ocrmypdf/_pipeline.py)。
- 调低阈值(例如
2.0)→ 更多页面被旋转,但同时误报更多; - 调高阈值 → 只有引擎非常有把握时才旋转。
建议先带 -v1 运行一次,查看每一页的置信度日志,再为特定文件挑选合适的阈值。
注意区分两个概念:
--rotate-pages用于基本角度错了(整页横/竖颠倒或差 90°)的情况;--deskew用于页面只是略微偏离水平线的情况(比如照片斜了 3°)。
非英语 OCR
除非显式指定,OCRmyPDF 默认假设文档是英语(默认语言 eng 定义于 src/ocrmypdf/_defaults.py)。语言用错会显著降低识别质量:
ocrmypdf -l fra LeParisien.pdf LeParisien.pdf
ocrmypdf -l eng+fra Bilingual-English-French.pdf Bilingual-English-French.pdf
指定的每一种语言都必须已安装对应的语言包,安装方式见 docs/languages.md。另外,Tesseract 引擎本身没有语言检测能力,未知语言必须手动指定。
Sidecar:同时输出 OCR 文本文件
ocrmypdf --sidecar output.txt input.pdf output.pdf
这会产生两个文件:PDF 与同目录下的 output.txt。使用 sidecar 时要注意它的边界:
- sidecar 只包含 OCR 识别出来的文本;文档中原本就存在的数字文本(digital text)不会出现在 sidecar 里;
- 若使用了
--pages,sidecar 只包含实际执行了 OCR 的那些页; - 因
--skip-big、--tesseract-timeout等原因被跳过的页不会写入 sidecar; - 若不想生成 PDF 只想要文本,可设
--output-type=none并把输出文件名设为-(重定向到标准输出); - 若需要提取 PDF 中全部文本(无论来源),请使用 Poppler 的
pdftotext或pdfgrep这类工具。
sidecar 字段在选项模型中类型为"路径或文件对象"(src/ocrmypdf/_options.py)。
对图片而不是 PDF 做 OCR
方案一:直接用 Tesseract
如果起点是图片,可以直接用 Tesseract 把图片转成带文本层的 PDF:
tesseract my-image.jpg output-prefix pdf
# 多张图片:用包含文件名列表的文本文件
tesseract text-file-containing-list-of-image-filenames.txt output-prefix pdf
Tesseract 的 PDF 输出质量相当不错——OCRmyPDF 内部在某些情况下也复用了它。但 Tesseract 缺少 OCRmyPDF 的诸多能力,如图像预处理、元数据控制和 PDF/A 生成。
方案二:img2pdf 管道
用 img2pdf 之类的工具先把图片无损地封装进 PDF,再把结果管道给 OCRmyPDF(- 表示从标准输入读取):
img2pdf my-images*.jpg | ocrmypdf - myfile.pdf
这是多张图片的推荐路线:img2pdf 生成的 PDF 不对图像做任何转码,保留了原始像素质量。
方案三:OCRmyPDF 直接吃单张图片
ocrmypdf --image-dpi 300 image.png myfile.pdf
OCRmyPDF 可以直接把单张图片转成 PDF 并 OCR。若图片的分辨率(DPI)信息缺失或错误,用 --image-dpi 覆盖(1 英寸 = 2.54 厘米,1 dpi = 0.39 dpcm)。注意:多张图片必须走 img2pdf 路线。
不推荐的方案
不建议用 ImageMagick 或 Ghostscript 把图片转 PDF:它们可能悄悄对图像转码或降采样,且不一定给出警告——而输入图像分辨率错误会直接损害 OCR 质量(见下文"提升 OCR 质量")。
图像预处理
OCRmyPDF 可以按需对每一页做图像处理,且所有页应用完全相同的处理。文档建议处理完人工抽查,因为这些操作可能移除有价值的内容,尤其是低质量扫描件。五个开关:
| 参数 | 作用 |
|---|---|
--rotate-pages |
判定每页正确方向并旋转(基本角度错误时) |
--remove-background |
检测并去除灰度/彩色图中的噪点背景;单色图像会被忽略;不要用在含彩色照片的文档上,可能把照片一起删掉 |
--deskew |
校正扫描倾斜,把页面旋转回正 |
--clean |
用 unpaper 在 OCR 前清理页面,不改变最终输出;降低 OCR 去背景噪声里"找字"的概率 |
--clean-final |
用 unpaper 清理后把清理过的页插入最终输出;务必逐页复查,确认未误删重要内容 |
两条重要提示:
- 图像处理通常会把 PDF 页面栅格化为图像,可能损失质量;
--clean-final与--remove-background的算法存在局限,部分图像上会留下可见瑕疵,用完后应目检文件。
在源码中,这些步骤对应 src/ocrmypdf/_pipeline.py 里的 preprocess_remove_background、preprocess_deskew、preprocess_clean 等预处理函数;--clean-final 会自动连带开启 --clean(选项校验器中显式处理,见 src/ocrmypdf/_options.py)。
示例:OCR 并校正倾斜
ocrmypdf --deskew input.pdf output.pdf
各图像处理开关可以任意组合,且书写顺序无关紧要——OCRmyPDF 始终以固定顺序执行流水线:rotate(旋转)→ remove background(去背景)→ deskew(倾斜校正)→ clean(清理):
ocrmypdf --deskew --clean --rotate-pages input.pdf output.pdf
只处理不 OCR:--ocr-engine none
把 --ocr-engine none 设为无 OCR 引擎时,OCRmyPDF 只做图像处理(或直接做 PDF/A 转换),跳过识别:
ocrmypdf --ocr-engine none --deskew --output-type pdfa input.pdf output.pdf
版本沿革上有两点需要注意:
- v17.0.0 起:
--ocr-engine none是关闭 OCR 的推荐写法。此前社区惯用的--tesseract-timeout 0惯用法已不再推荐,因为项目正把 Tesseract 从"默认引擎"位置上挪开; - v14.1.0 起:
--tesseract-timeout 0不再连带禁掉 Tesseract 的其他用途(例如 deskew 的倾斜角度估计)。如需单独控制非 OCR 操作的超时,用--tesseract-non-ocr-timeout。
移除 PDF 中的 OCR 文本层
若只想删掉不可见的 OCR 文本层、同时保持页面像素级原样(不栅格化、不动图像、输出更小),使用 --mode strip:
ocrmypdf --mode strip input.pdf output.pdf
典型场景:某份 PDF 的 OCR 结果根本不可用,只想把糟粕清掉。其边界要清楚:
--mode strip只移除以 PDF 文本渲染模式 3(不可见) 绘制的文本——这正是 OCRmyPDF 及多数 OCR 工具叠加可搜索层的方式;- 某些 OCR 产品(以及 OCRmyPDF v2.2 及更早版本)采用"绘制可见文本 + 上层盖不透明图像"的旧方案。那种文本属于页面可见内容,strip 无法在不改变外观的前提下移除它;
- 若必须连同可见文本一起剥离,只能把整页栅格化成"图像袋子"PDF——代价是每页重建为图像,文件通常变大、矢量内容丢失:
ocrmypdf --ocr-engine none --force-ocr input.pdf output.pdf
不 OCR 只优化图像
ocrmypdf --ocr-engine none --optimize 3 --skip-text input.pdf output.pdf
这条组合拳用于纯粹的体积优化:跳过 OCR、跑满优化等级 3。
v17 新特性
选择光栅化器
v17.0.0 起,OCRmyPDF 支持用 pypdfium2 或 Ghostscript 把 PDF 页面栅格化成图像。pypdfium2 通常更快,可用时优先选用:
# 自动选择(默认)- 可用时优先 pypdfium
ocrmypdf --rasterizer auto input.pdf output.pdf
# 显式使用 pypdfium2(需 pip install pypdfium2)
ocrmypdf --rasterizer pypdfium input.pdf output.pdf
# 显式使用 Ghostscript
ocrmypdf --rasterizer ghostscript input.pdf output.pdf
源码中的校验器确认 --rasterizer 只接受 auto / ghostscript / pypdfium 三个取值(src/ocrmypdf/_options.py),默认值为 auto。
不依赖 Ghostscript 的 PDF/A
v17.0.0 起,只要安装了 verapdf,OCRmyPDF 可以在不经过 Ghostscript 的情况下产出 PDF/A:先做"投机性转换",再用 verapdf 校验合规。这条路更快,也绕开了 Ghostscript 的一些限制:
# 投机转换 + verapdf 校验(默认行为)
ocrmypdf --output-type auto input.pdf output.pdf
# 显式要求基于 Ghostscript 的 PDF/A 转换
ocrmypdf --output-type pdfa input.pdf output.pdf
用 --mode 取代旧标志
v17.0.0 引入的 --mode(短形式 -m)把三种 OCR 行为合并进一个选项:
# 取代 --skip-text
ocrmypdf --mode skip input.pdf output.pdf
# 取代 --force-ocr
ocrmypdf --mode force input.pdf output.pdf
# 取代 --redo-ocr
ocrmypdf --mode redo input.pdf output.pdf
# 短形式
ocrmypdf -m skip input.pdf output.pdf
旧标志作为别名继续可用。这一点从源码可确认:选项模型里 force_ocr / skip_text / redo_ocr 已成为 mode 的向后兼容属性(src/ocrmypdf/_options.py),且在模型构建前有一个专门的校验器把旧布尔标志翻译成 ProcessingMode 枚举、并检测互相冲突的写法(src/ocrmypdf/_options.py)。此外还有前文用到的 strip 模式。
mode 还有兼容性约束:redo 模式与 --deskew、--clean-final、--remove-background 互斥(这些选项会改变文件外观),源码中有显式校验报错(src/ocrmypdf/_options.py)。
只处理指定页
ocrmypdf --pages 2,3,13-17 input.pdf output.pdf
语法要点:
- 连字符
-表示页码区间,逗号分隔页码; - 想带空格写列表时整体加引号:
--pages '2, 3, 5, 7'; - 特殊记号
end(不区分大小写)指最后一页:--pages 3-end表示从第 3 页到最后一页,--pages end表示只处理最后一页。
ocrmypdf --pages 3-end input.pdf output.pdf
ocrmypdf --pages end input.pdf output.pdf
行为细节(部分由源码印证):
- 页码列表有重复或重叠时 OCRmyPDF 会告警;重复项会自动去重,因为底层真正生效的是页码集合(见 src/ocrmypdf/_options.py 中的页码解析逻辑,
end会被延迟到知道总页数后再解析); - 使用文档自身的"印刷页码"(如书前置部分的罗马数字)是不被考虑的——OCRmyPDF 只从文件开头数"虚拟纸张";
- 页码乱序书写没关系,OCRmyPDF 会自动排序。
一个重要陷阱:--pages 只限制图像处理与 OCR 的作用范围。文件级操作——优化全部图像/页面、转换 PDF/A——默认仍然作用于整个文件。若只想 OCR 标题页、其余尽量不动,应同时关掉这些"全文件"步骤:
ocrmypdf --pages 1 --output-type pdf --optimize 0 input.pdf output.pdf
重做已有的 OCR
对用其他 OCR 软件、或旧版 OCRmyPDF / Tesseract 处理过的文件重新 OCR,使用 --redo-ocr(正常情况下,OCRmyPDF 遇到已含 OCR 的文件会直接报错退出):
ocrmypdf --redo-ocr input.pdf output.pdf
适用场景:吃下 Tesseract 新版本的识别精度提升,重跑存量文件。
- 该模式不栅格化,不会降质或丢矢量内容;
- 混合文件(纯数字文本 + OCR 层并存)中,数字文本被忽略,只替换 OCR 层;
- 因为不改变外观,它与图像处理选项(
--deskew、--clean-final、--remove-background)不兼容; - 有些旧格式无法识别:OCRmyPDF v2.2 及更早产物是"可见文本 + 不透明图像覆盖"的内部结构,这种 OCR 无法被检测,也无法被替换;
- 若
--redo-ocr不适用,退路是--force-ocr:强制把所有页栅格化后重做 OCR,代价是可能降质、丢失矢量内容。
提升 OCR 质量
图像预处理本身就是提升质量的手段:
--rotate-pages与--deskew保证 OCR 开始前页面方向正确;--remove-background与--clean减少背景噪声对识别的干扰;--oversample DPI在 OCR 前把图像重采样到更高分辨率,也可能改善结果(该参数合法范围为 0–5000 DPI,见 src/ocrmypdf/_options.py)。
反过来,输入图像分辨率标注错误会直接拉低 OCR 质量——因为 OCRmyPDF 依据 DPI 推算每个像素可能对应的字号范围,DPI 错了,字号候选区间也就错了。这也是前文不推荐 ImageMagick/Ghostscript 转图的根本原因。
PDF 优化
OCR 完成后,OCRmyPDF 默认会对 PDF 内图像做无损优化;即使没有发现可 OCR 的文本,优化照样执行。
--optimize N(短形式 -O)控制优化等级,N 取值 0–3,类比 GCC 编译器优化等级,默认 -O1(源码中 optimize: int = 1,见 src/ocrmypdf/_options.py):
| 等级 | 含义 |
|---|---|
-O0 |
关闭大部分优化 |
-O1(默认) |
无损优化:把图像转成更高效的编码、压缩未压缩对象、启用对象流 |
-O2 |
加上有损优化与颜色量化 |
-O3 |
更激进的优化,目标更小、图像质量目标更低 |
ocrmypdf --optimize 3 in.pdf out.pdf # 目标:尽量小
各等级的完整行为(含 JBIG2、pngquant、fast web view 等)见 docs/optimizer.md。个别用户可能考虑开启有损 JBIG2,见 docs/jbig2.md。
最后一条提醒:即使 --optimize 1(纯无损档),图像处理与 PDF/A 转换本身也可能引入有损变换,优化等级不能替你保证"零损失"。
数字签名 PDF
OCRmyPDF 不能一边保留数字签名一边加 OCR 层,二者不可兼得:
- 默认行为:拒绝修改任何带签名的 PDF,无论其他参数如何设置;
- 用
--invalidate-digital-signatures可覆盖此行为——顾名思义,所有数字签名都会被作废; - 用数字证书加密的文档 OCRmyPDF 根本无法打开;
- 版本沿革:v14.4.0 之前的 OCRmyPDF 会不告而废文档中已有的数字签名,处理旧作业时要留意。
小结
OCRmyPDF 的 Cookbook 本质上是一张"参数组合表":日常任务是 input.pdf output.pdf 加少量开关;扫描件质量差时叠加 --rotate-pages --deskew --remove-background --clean;存量重跑用 --redo-ocr;纯瘦身用 --ocr-engine none --optimize 3 --skip-text。所有参数的默认值与取值约束都能在 src/ocrmypdf/_options.py 的 OcrOptions 模型和 src/ocrmypdf/_defaults.py 中核对,图像预处理的具体执行顺序可在 src/ocrmypdf/_pipeline.py 中追溯——这使本文每个命令行示例都有源码级依据可查。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00