README
¶
ofd-compare
比较两份或多份 OFD,以一份为基准,为每个其他文件生成独立的差异结果。源文件只读。
ofd-compare -o comparison.html original.ofd revised.ofd final.ofd
ofd-compare --baseline 2 -o comparison.json version1.ofd version2.ofd version3.ofd
ofd-compare --visual=false --format text original.ofd revised.ofd
ofd-compare --page-match number --dpi 96 --pixel-tolerance 3 -o visual.html a.ofd b.ofd
ofd-compare --visual=false --fail-on-difference -o diff.json a.ofd b.ofd
ofd-compare --pages "1-3,5" -o selected.html a.ofd b.ofd
ofd-compare --min-region-pixels 4 -o focused.html a.ofd b.ofd
ofd-compare --page-map "2:3,4:5" -o mapped.html a.ofd b.ofd
ofd-compare --external-images -o comparison.html original.ofd revised.ofd final.ofd
源码运行:在仓库根目录使用 go run ./cmd/ofd-compare 替换程序名。构建随 make build-tools,单独打包使用 make package-compare。
对比内容
- 输入大小、文档体数量、页数、页面尺寸,文档标题、作者、主题和生成软件元数据。
- 包内完整目录与文件清单,新增、删除、修改;摘要相同的删除/新增文件配为移动。
- 解压后的 SHA-256,不因 ZIP 压缩、条目顺序或时间戳变化误报文件内容改变。
- HTML 完整文件清单逐行对齐基准与目标:相同路径及已识别的移动文件放在同一行,展示双方大小和比较状态;修改、新增、删除、移动用红色标记,缺失一侧显示
—。即使文件大小相同,也会按内容摘要识别修改。 - 清单支持路径搜索、“只看不同”及状态、类型组合筛选,显示筛选结果数量和无匹配提示,可一键重置。路径搜索忽略大小写,匹配任一侧路径;类型匹配任一侧文件。点击差异行或通过键盘激活“查看详情”,自动展开、突出显示并跳转到对应的 XML 差异或资源预览。各目标分别保留筛选条件,筛选只影响清单展示。
- 文件详情顶部和底部提供“返回文件清单”,返回并高亮原文件行,恢复键盘焦点,保留搜索和筛选条件。直接展开文件详情也能返回对应行;原行已被新筛选条件隐藏时返回搜索框。
- XML 元素、属性、文字和子元素顺序;命名空间使用 URI 关联,忽略前缀、属性顺序、注释和元素间缩进。
TextCode空白保留。原始字节变化与结构变化分别报告。 - HTML 提供格式化 XML 左右对照,按行对齐新增、删除和修改,变化侧分别标红、标绿;较长的相同片段默认折叠,保留首尾各 3 行上下文,支持展开全部或折叠相同部分。原字段差异可单独查看,报告区分“仅格式变化(XML 结构相同)”“XML 结构或内容变化”、新增、删除和结构分析不可用。
- 展开/折叠按钮作用于全部相同片段,包括短片段和上下文;旁边显示当前折叠状态。已全部展开/折叠时禁用对应按钮,没有相同行时两个按钮均禁用。
- 页面文字的多处删除、新增和替换;按 Unicode 字符比较,中文、表情和空白完整保留。文字按正文和可用模板中的内容顺序提取,不做 OCR。
- 页面画面:变化像素数量、比例、多个差异区域、原图和差异图。HTML 支持点击区域框或区域按钮查看局部放大,放大倍数可调,前后图及差异图同步滚动;也支持切换目标文件、变化页过滤、逐区域导航和透明叠加。
- 图片、字体及其他资源的文件变化;支持格式的小图片资源内嵌预览。字体程序按二进制比较,资源 XML 中的字体名称与属性通过 XML 差异查看。
auto 页面匹配先在同一文档体中按相同页面模型内容、唯一的相同非空文字关联,再以这些页面为定位点,在相邻范围内寻找文字相近且无明显歧义的修改页,最后在定位范围内按顺序补齐。文字相似度最多分析前 4096 个非空白字符,累计搜索工作量超过 400 万时回退到定位点和顺序配对。新增或移位会显示前后页码。扫描页、复杂改版或重复内容的配对仍可能不符合预期,可用 --page-map "2:3,4:5" 优先指定基准第 2 页对应目标第 3 页、基准第 4 页对应目标第 5 页,其余页面自动匹配。映射分别用于每个目标,两侧页码不能重复,必须在所选页面中,且仅适用于 auto。也可用 --page-match number 固定按选中页的全局顺序配对。所有报告页码从 1 开始,多文档体按文档顺序累计。
每组页面会显示配对依据:手工映射、页面内容摘要相同、唯一相同文字、文字相似度、自动顺序兜底、显式顺序匹配或未匹配。HTML 会提示复核按顺序兜底配对的页面,必要时使用 --page-map 调整。依据为“内容摘要相同”时,仅表示页面模型相同,资源变化仍可能造成视觉差异。相似度分数表示配对时使用的文字特征相似度,不是匹配正确概率或画面相似度。
JSON 的 pages[].match.method 分别使用 manual、content、text、text_similarity、sequence、number、unmatched;文字相似度配对额外提供 0–1 的 text_similarity。search_limited: true 表示相似度搜索达到工作量上限后的顺序配对或未匹配结果。文本和 Markdown 也列出未变化页面的配对依据,配对说明不会改变页面相同判定和差异计数。
HTML 在“页面对比”下提供“调整页配对并导出 --page-map”。编辑器预填当前配对,列出所选的基准页,可修改对应的目标页码;重复、非正整数或超出本报告所选范围时会标红并禁止导出。清空一行表示让该页重新自动匹配,不表示强制删除/新增。可以恢复原配对、清空全部映射,并复制参数或下载 .txt;各目标草稿独立,刷新页面后恢复原配对。
导出只针对当前基准与目标,包含 --page-match auto,有页范围时也包含 --pages。重新运行时将这份基准放在第一位、目标放在第二位,例如:
ofd-compare --page-match auto --pages "2-4" --page-map "2:4,3:2" \
-o remapped.html baseline.ofd target.ofd
编辑后的草稿用于生成参数,当前报告中的文字、图像和配对依据仍显示原计算结果;需要重新运行后查看新的差异。只看变化页面不会隐藏编辑器的其他基准页。剪贴板不可用时会选中参数,按 Ctrl+C/Command+C 手工复制即可。
--pages "1-3,5" 在每份文件中分别选择第 1、2、3、5 页,然后在选中页面之间配对,结果保留原始页码。重叠区间和重复页码会合并;超出某份文件的页码忽略,但某份文件一页都未选中时明确报错。范围之外的页面不提取文字或渲染。包内文件和 XML 仍按整包对比,因此未选中页的文件变化仍会出现在文件差异中;--fail-on-difference 也仍然检查整份报告。
视觉区域按约 1 毫米边长的网格进行八邻域聚合,区域框覆盖变化网格,原始像素总数仍逐像素计算。--min-region-pixels 可过滤小噪点区域,默认 1 保留所有区域;过滤不会把原本有变化的页面判为相同。每页最多列出变化像素最多的 200 个区域,再按从上到下、从左到右排序;达到上限时报告明确提示。局部放大由浏览器从整页图按需裁出,无需另存大量局部图片。
文字对比使用有界的编辑距离搜索,通常可以分别显示多处修改;大片重写超过搜索上限时回退为完整变化段落对照,报告以 text_diff_coarse 标记,双方原文完整保留。
XML 对照统一命名空间前缀、属性顺序和缩进,忽略注释及 XML 声明;“仅格式变化”也包括这些不影响当前结构字段的变化。文字中的换行、回车、制表符显示为字符引用,保留 TextCode、xml:space 和混合内容中的有效空白。行号属于规范化后的显示内容,原始字节以输入文件为准。每侧最多展示 256 KiB 源 XML、4000 个元素节点、4000 行及 1 MiB 格式化内容;超限时说明原因,保留结构分类及字段差异。展示上限固定,不随 --max-xml-bytes 增大。行对齐超过 512 步编辑距离或 400 万扫描工作量时,回退为完整变化段落对照并设置 xml_view.coarse;JSON 通过 xml_view.blocks 保留双方内容。
视觉对比使用同一次运行中的本机渲染环境;缺失的字体需先安装合适系统字体。视觉差异能发现共享资源变化对页面的影响,即使页面 XML 自身没有修改。像素容差只影响视觉结果,文件和文字差异仍然记录。改变页尺寸时,超出另一页的区域也计为变化。
选项与输出
| 选项 | 默认值 | 说明 |
|---|---|---|
-o, --output |
标准输出 | 报告路径;- 写 stdout,禁止覆盖任一输入或它的链接 |
--format |
按扩展名推断 | text、markdown、json、html;stdout/无扩展名为 text |
--baseline |
1 |
基准在位置参数中的序号 |
--page-match |
auto |
auto 或 number |
--page-map |
无 | 手工页映射,例如 2:3,4:5;先于自动配对,仅适用于 auto |
--pages |
全部页面 | 各输入中从 1 开始的全局页码,例如 1-3,5;先选页再配对 |
--visual |
true |
设置 --visual=false 跳过页面渲染 |
--dpi |
72 |
范围 10–300 |
--pixel-tolerance |
0 |
RGB 每通道容差,范围 0–255 |
--min-region-pixels |
1 |
区域最小变化像素数;过滤只影响区域展示,保留原始像素统计和相同判定 |
--max-xml-bytes |
8388608 |
单文件 XML 分析上限;超出后保留摘要并明确标记跳过结构分析 |
--max-xml-structure-bytes |
33554432 |
每个 XML 字段表的估算大小上限;超出后保留文件差异并记录诊断 |
--max-changes |
200 |
每个 XML 的差异明细上限,截断时报告标记 |
--max-page-pixels |
10000000 |
单页及配对后范围的像素上限 |
--max-total-pixels |
1000000000 |
全部对比累计实际页面渲染像素上限;缓存命中不重复扣减,淘汰后重渲染仍扣减 |
--baseline-cache-bytes |
67108864 |
多目标比较时基准页 RGBA 缓存上限,按最近最少使用淘汰;-1 禁用,0 使用默认值 |
--max-preview-bytes |
67108864 |
页面与资源预览累计编码后的 PNG 字节上限,多目标共享;外置图片也计入 |
--max-report-bytes |
268435456 |
保留的报告数据和最终输出字节上限;超限返回错误 |
--external-images |
false |
图片保存到 HTML 旁新建的 ofd-compare-images-* 目录;须指定 HTML 输出文件 |
--fail-on-difference |
false |
有差异时退出码为 1 |
--version, -v |
输出仓库统一版本 | |
--help, -h |
输出帮助 |
HTML 默认是图片内嵌的单文件,可直接在浏览器本地打开,无网络依赖。使用 --external-images -o report.html 时,PNG 在生成过程中写入报告旁新建的独立目录,报告仅保留相对引用;相同 PNG 按摘要共用文件。共享报告时须同时携带图片目录,并保持相对位置。失败会清理本次新建的图片目录,并保留已有报告;成功替换旧报告后,旧图片目录由使用者自行清理。相同输入不生成图片时不会留下空目录。
JSON 默认同样包含视觉图片,关闭视觉对比可以减小报告。文本与 Markdown 提供差异明细;Markdown 使用预格式化正文保存包内路径与原始 XML 文本。文件输出先写临时文件,报告成功后替换目标文件;错误写 stderr。
包内总解压量限制为 1 GiB,最多 100000 条目和 10000 页。仅对发生内容变化及新增/删除的 XML 进行结构分析,每次只保留当前文件两侧的字段表;未分析的 XML 结构摘要字段留空,基准侧的已分析摘要在多个目标之间保留。XML 另限制 200000 节点、128 层和字段表估算字节数,超过后标记结构分析不可用。图片资源预览仅处理不超过 2 MiB、100 万像素的可解码资源。像素、预览图或报告预算超限会返回错误,可降低 DPI、使用外置图片或显式调整相应限制;外置图片减少报告对象的内存和 HTML 体积,但不会绕过 PNG 预算。报告数据预算按逐条紧凑 JSON 大小检查,实际输出还会计入缩进、模板与重复展示;这些预算不等同于整个进程的内存上限。
多目标视觉比较默认启用 64 MiB 基准页缓存,按实际 RGBA 像素缓冲区大小计量;超出容量的单页不缓存。缓存命中复用基准图像,像素预算只计算实际发生的渲染。单目标比较不保留额外缓存。缓存不能容纳全部基准页时,后续目标可能需要重新渲染部分或全部页面;可调整 --baseline-cache-bytes,或设为 -1 禁用。
结果含义与范围
equal 表示包内路径和文件解压内容相同、所选页的页码和页面内容相同,且启用视觉时画面也相同。pages_equal 单独表示所选页面的比较结果。它们不表示整个 ZIP 的字节完全一致。只改变 XML 缩进时,文件仍标为修改,但显示“XML 结构相同”。资源 ID 重新编号仍计入 XML 结构差异;第一版不推断所有资源 ID 的等价关系。
页面文字比较不包含 OCR、注解外观或印章中的语义文字;视觉比较包含渲染器支持的这些外观。页面对象的逐项匹配、字符级几何定位、字体字形级比较和签名有效性比较不在本版范围。签章、附件、历史版本文件通过包内文件与 XML 差异检查;签名有效性使用 ofd-validator/签章验证 API 单独核验。
退出码:
| 退出码 | 含义 |
|---|---|
0 |
成功生成报告,或输出帮助/版本;默认允许存在差异 |
1 |
报告已生成,且启用了 --fail-on-difference 并发现差异 |
2 |
参数、格式或输出覆盖输入错误 |
3 |
读取、解析、渲染、预算、取消或报告写入失败 |
通过 go run 运行时,Go 启动器会把程序非零退出码包装为自己的退出状态;脚本判断建议使用构建后的程序。