科技 · 实用指南
PDF 图片数量对不上?分清对象、放置次数与实际可见画面
同一图片复用、页外放置和不透明遮盖会带来不同计数。四组实测对照说明,各种检查分别能验收什么。

PDF 图片清单不等于读者眼前能看到的图片数。我们的受控样例只有一个嵌入位图,却放置了三次:两处与页面相交,一处位于页外。在页内第二处上方加白色不透明遮盖后,渲染画面从两个蓝色方块变成一个,图片清单却没有改变。
先明确需要的是独立嵌入素材、每次放置记录,还是页面渲染外观,再保留对应证据。现有 PyMuPDF 提取与裁切方法仍然有效;本文补充的检查是:即使图片包围框与页面相交,也不能证明它在最终画面中可见。
先定义输出,再选择计数
导出素材时,记录嵌入图片身份与提取结果;同一图在多页复用,不一定要当作多个独立素材。制作放置清单时,则应保留每次出现的页码、bbox和transform,即使xref重复。要得到页面视觉裁切,应渲染目标区域,不能假设导出的原始图片等同于合成后的画面。
这些目标不能共用一个成功数字。按xref去重可以适用于素材库,但若把它当成唯一清单,就会丢失放置记录。反过来,资源行数也不能证明有同样多的独立原图。PyMuPDF 已说明重复出现、可能存在未绘制资源,以及xref为0代表内联图片或无法识别的引用。不要把所有xref为0的条目合并为一个已知素材。
建立只读的出现记录
记录准确PDF哈希、物理页码、库版本与输出目标。下面代码对适当大小、已获授权的工作副本检查第一页,不重写PDF。保留出现序号、xref、bbox和transform,不要改成只以xref为键的字典。其他页面使用相应的从零开始索引。 ```python import pymupdf with pymupdf.open("input.pdf") as doc: page = doc[0] # first physical page refs = page.get_images(full=True) placements = page.get_image_info(xrefs=True) print("resource rows:", len(refs)) print("unique positive xrefs:", len({r[0] for r in refs if r[0] > 0})) print("placements:", len(placements)) for occurrence, item in enumerate(placements): print(occurrence, item["xref"], item["bbox"], item["transform"]) ```
独立检查可用 pdfimages -list "input.pdf",它列出页码、图片编号、类型和对象ID,不写提取图片。检查退出状态并对比重复对象ID,不要把每一行当作独立素材。报告中的宽高描述嵌入像素,而不是页面上绘制的大小;mask和smask会作为不同类型列出,本次简单实验没有这两类。
先解释裁切差异,再认定图片丢失
PyMuPDF 的image-info清单不限制在可见页面矩形内,而 get_text('dict') 默认使用该范围,并只包含完全位于裁切区内的图片。已有支持讨论用 clip=pymupdf.INFINITE_RECT() 解决计数差异;clip=None 仍采用常规页面范围。这里承认这一现有解法,不把它包装成新发现。
无限裁切改变的是清单范围,不会让页外内容在页面渲染中变得可见。get_text('dict') 还会加载图片二进制数据,get_image_info 则避免加载这些字节。只有确实需要比较时,才在适当大小的受影响页执行较重检查。位图清单为空也不代表页面为空,文字与矢量绘制命令属于其他内容。
看四组实测对照
我们创建并重新打开四份200×150点、无旋转的单页PDF,位图为自制20×20像素RGB方块。单次放置组有1个独立xref、1次image-info出现、1个默认图片块,渲染可见1个蓝块。三次放置组把同一个xref用于两处页内和一处页外位置:资源记录3、出现次数3、默认图片块2、无限范围图片块3,与页面相交包围框2。
在页内第二处上方再画白色不透明矢量矩形,所有上述清单数字不变,画面却只剩第一个蓝块。像素采样验证未遮盖处是蓝色、遮盖处是白色。另一个纯矢量方块样例的资源、image-info和图片块都为0,但渲染仍有蓝色图形。Poppler 在两组复用样例中均列出对象ID相同的三条图片记录。九项有意义的断言通过;这些已知对照不构成通用可见性检测器。
按任务目标验收
若要放置清单,导出前对比完整出现记录与预期位置;若要素材,另行说明身份与去重规则;若要外观,则检查页面渲染,例如 page.get_pixmap(),以及真正需要的裁切。保留原PDF,不要因为数字不一致就删除图片。页面相交只是几何判断,白色遮盖对照已经证明它不能单独保证可见。
实验限于Linux下的PyMuPDF 1.26.6、MuPDF 1.26.11及pdfimages 24.02.0,没有测试蒙版、透明度、旋转页面、Form XObject、可选内容、注释或私人文档。复杂重叠与合成还需要更多检查。看起来正确的裁切只证明外观结果,不证明对象已经删除,也不是涂黑脱敏或安全审计。
