PPT 图片差异为何会漏掉“删掉一张相同图片”:从集合比较改为计数比较

举报
yd_225778114 发表于 2026/10/15 11:33:49 2026/10/15
【摘要】 用合成 PPT 复现“删除一张重复图片却显示图片变化 0”的问题,说明哈希集合如何丢失出现次数,并用 Python Counter 给出修正与四组验收用例。

比较两份 PPT 时,“图片有没有变”看起来可以用内容哈希解决:抽取每张图片,计算哈希,然后比较旧版和新版的哈希集合。但图片是可以重复出现的。同一页贴了两份完全一样的图,只删除其中一份时,哈希集合仍然是同一个集合。若实现只比较集合,就会把一次真实的删除判成没有图片变化。

我用一个合成文件复现了这个边界:旧版只有一页,标题下有两张字节完全相同的 20×20 红色 PNG;新版保留其中一张,其余不变。当前脚本的摘要报告却显示“图片变化 0、修改页面 0”。这个结果不代表用户没改过文件,只说明检测逻辑没保留重复图片的出现次数。测试文件不含真实文档或个人资料。

集合和多重集合的差别

假设每张图的内容哈希都是 A:

旧版:[A, A]  →  集合 {A}
新版:[A]     →  集合 {A}

旧版集合减新版集合、新版集合减旧版集合都为空。把列表转为哈希到图片的字典也一样:第二张图片会覆盖第一张对应的键。这个结构适合回答“某种图片内容是否存在”,却不能回答“同一内容出现了几次”。

对此,最小且明确的改法是按哈希计数。Python 的 Counter 可以直接表达多重集合差集:

from collections import Counter

old_hashes = ["A", "A"]
new_hashes = ["A"]
removed = Counter(old_hashes) - Counter(new_hashes)
added = Counter(new_hashes) - Counter(old_hashes)

assert removed == Counter({"A": 1})
assert not added

这段计算只回答数量差异。报告若还需要展示“删掉的是页面上哪一张”,则要保留每个哈希对应的出现列表,并按位置或形状 ID 匹配:先把旧、新图片按哈希分组,再从对应组里配对相同位置的实例;剩余的旧实例记为删除,剩余的新实例记为新增。不能先用字典覆盖同哈希实例,再尝试恢复位置信息。

复现与验收

用 python-pptx 可以在同一页放入同一份 PNG 字节两次,保存为旧版,再只放一次保存为新版。执行差异工具时,应至少看到删除一张图片,以及该页存在修改。验收不应仅检查总页数,因为两个文件都仍然只有一页。

建议补四组边界用例:[A,A] → [A] 应报告删除 1;[A] → [A,A] 应报告新增 1;[A,A] → [A,A] 应报告无变化;[A,B] → [A,C] 应分别报告 B 删除与 C 新增。若工具还区分“图片移动”与“图片替换”,再加入同内容跨位置和不同内容同位置的例子,避免把数量变化与位置变化混为一谈。

更一般地说,页面中的图片、表格单元、批注等对象都可能重复。选择数据结构前先问清楚需求:只关心“是否存在”,可以用集合;关心“新增或删除多少个”,就必须保留计数;关心“具体哪一个实例发生变化”,还需要对象级匹配。这个区别决定了差异报告是否可信。

复现记录:GitCode Issue #37。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。