如何用 OCRmyPDF 的 --redo-ocr 重新执行旧 OCR 文件并保留原有版面
手上有一份已经做过 OCR 的 PDF,想换用更新的 Tesseract 或 OCRmyPDF 重新识别,却直接报 page already has text! 被终止?OCRmyPDF 的 --redo-ocr 参数就是为这个场景设计的:它检测并移除文件中已有的隐藏 OCR 文本层,然后重新执行 OCR,整个过程不栅格化页面,因此不会降低图像质量或丢失矢量内容——原有版面得以保留。
为什么默认模式处理不了旧 OCR 文件
如果 PDF 中的页面看起来含有文本,OCRmyPDF 默认会直接退出且不修改文件,以避免重复处理已 OCR 过或"天生数字"的文档。典型报错如下(文档示例):
ERROR - 1: page already has text! – aborting (use --force-ocr to force OCR)
面对这种情况,docs/errors.md 列出了三个选项:
ocrmypdf --force-ocr:将所有内容栅格化后执行 OCR,适合前次 OCR 程序失败或文档含文本水印的情况;ocrmypdf --skip-text:跳过含文本页的 OCR 和处理,原样复制到输出;ocrmypdf --redo-ocr:扫描文件中已有的 OCR(不可打印文本),移除它并重新执行 OCR。
--redo-ocr 与另外两个选项不同:可打印的矢量文本不会被纳入 OCR,因此它也适用于数字内容与扫描内容混合的文件。
执行 --redo-ocr
前提只需已安装 OCRmyPDF(见 docs/installation.md),可用 ocrmypdf --version 确认安装的版本。基本命令如下:
ocrmypdf --redo-ocr input.pdf output.pdf
自 17.0.0 起,--redo-ocr 被整合进统一的 --mode 参数,--redo-ocr 保留为向后兼容的静默别名,二者等价:
# 17.0.0 起推荐使用
ocrmypdf --mode redo input.pdf output.pdf
# 短形式
ocrmypdf -m redo input.pdf output.pdf
--mode redo 的实际处理流程(见 docs/advanced.md):
- 对文件做详细文本分析,把文本分为可见与不可见两类;
- 剥离开源 OCR 留下的不可见文本层;
- 生成每一页的图像,并把可见文本区域遮蔽掉;
- 将页面图像送去 OCR,新识别的文本作为 OCR 层插入。
如果文件同时包含数字文本和含文字的位图,OCRmyPDF 会在不干扰现有文本的前提下定位位图中的文字并重新识别。由于这一过程不栅格化页面,矢量内容和版面布局保持不变——这也是它与 --force-ocr 的核心区别。
与图像预处理参数互斥
--redo-ocr 会改变文件中文字的位置与内容,因此与那些会改变文件外观的图像预处理选项不兼容。同时使用以下任一参数会直接报错:
--redo-ocr (or --mode redo) is not currently compatible with --deskew, --clean-final, and --remove-background
该互斥在 src/ocrmypdf/_options.py 的校验逻辑中强制。需要纠偏、去背景等处理时,先单独完成图像预处理,再对结果运行 --redo-ocr。
验证结果
仓库测试套件中的 tests/test_main.py 展示了核对 redo 结果的思路:在输入与输出 PDF 上分别做详细文本分析(detailed_analysis),确认三点——处理前后页面都有文本(has_text 为真),且处理后的文本区域与处理前不同,说明旧文本层确实被替换而非简单复制。你可以用任何 PDF 文本分析工具做类似对比,或直接在 PDF 阅读器中搜索新识别出的关键词来确认文本层已更新。
无法 redo 的情况与回退方案
以下情形 --redo-ocr 无法覆盖(均来自 docs/cookbook.md 与源码):
- OCRmyPDF v2.2 及更早版本生成的文件:内部以"可见文本 + 顶部覆盖不透明图像"的方式表示,这种情况无法被检测到;
- 以可见方式渲染的 OCR 文本:某些 PDF OCR 方案先把文字画出来再覆盖掉,OCRmyPDF 无法将其与真实文本区分,因此不会 redo 这类文本;
- 含可填写表单(AcroForm)的 PDF:直接抛出
This PDF has a user fillable form. --redo-ocr (or --mode redo) is not currently possible on such files.(见 src/ocrmypdf/_pipeline.py); - Tagged PDF 的结构标记:
--redo-ocr剥离并重写文本层后,原有的逻辑结构树与页面内容不再对应,会被丢弃(见 docs/advanced.md "Tagged PDFs and structural markup" 一节)。
如果 --redo-ocr 对上述原因不生效,可以回退到 --force-ocr:
ocrmypdf --force-ocr input.pdf output.pdf
注意 --force-ocr 会强制栅格化所有页面,可能降低质量或丢失矢量内容,只在 redo 走不通时使用。
参考文档
- docs/cookbook.md:"Redo existing OCR" 一节,覆盖 redo 的适用与不适用场景;
- docs/advanced.md:
--mode四种模式(default/force/skip/redo)的行为对照表; - docs/errors.md:"Page already has text" 报错的处理选项。
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 StartedRust0634
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java01
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java00
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00