如何在C++或Python中验证图像文件的完整性?

2 投票
3 回答
2394 浏览
提问于 2025-04-17 03:47

我想检查一下图片是否下载完整。有没有什么库可以用来做这个?我想验证的图片格式包括jpeg、png、bmp等等。

3 个回答

0

你可以尝试把图片加载到内存中(比如用PIL这样的工具),但有些图片可能在不完整的情况下也能加载成功。举个例子,一个动画GIF如果只加载了头部和第一帧,你可能不会发现后面的帧缺失了,因为它看起来还是正常的。

一个更可靠的方法可能是使用一些额外的通信方式。比如,不要只是盯着一个文件夹,等新文件出现就处理,而是想办法和下载过程连接起来,让它在准备好时给你发个信号。

2

我使用了Python的Pillow模块(PIL)和Imagemagick的封装库Wand(用于psd和xcf格式),来检测损坏的图片。原始的答案和代码片段可以在这里找到。

我还在我的Python脚本中实现了这个解决方案,代码可以在GitHub上找到

我还发现,损坏的文件(jpg格式)并不总是“坏掉”的图片,也就是说,有时候损坏的图片文件仍然是有效的图片文件,虽然原始的图像丢失或被修改,但你仍然可以加载它。

为了完整起见,我引用了完整的答案:

你可以使用Python的Pillow(PIL)模块,支持大多数图片格式,来检查一个文件是否是有效且完整的图片文件。

如果你想检测损坏的图片,@Nadia Alramli正确地建议使用im.verify()方法,但这个方法并不能检测所有可能的图片缺陷,例如,im.verify无法检测到截断的图片(大多数查看器通常会加载带有灰色区域的图片)。

Pillow也能检测这些类型的缺陷,但你需要进行一些图像处理或图像解码/重新编码才能触发检查。最后,我建议使用以下代码:

try:
  im = Image.load(filename)
  im.verify() #I perform also verify, don't know if he sees other types o defects
  im.close() #reload is necessary in my case
  im = Image.load(filename) 
  im.transpose(PIL.Image.FLIP_LEFT_RIGHT)
  im.close()
except: 
  #manage excetions here

如果有图片缺陷,这段代码会抛出异常。请注意,im.verify的速度大约是进行图像处理的100倍(我认为翻转是比较便宜的转换之一)。使用这段代码,你可以以大约10 MBytes/秒的速度验证一组图片(现代的2.5Ghz x86_64 CPU)。

对于其他格式如psdxcf等,你可以使用Imagemagick的封装库Wand,代码如下:

im = wand.image.Image(filename=filename)
temp = im.flip;
im.close()

不过,根据我的实验,Wand并不能检测到截断的图片,我认为它会将缺失的部分加载为灰色区域,而不会提示。

我听说Imagemagick有一个外部命令identify,这个命令可能能完成这个工作,但我还没有找到以编程方式调用这个功能的方法,也没有测试过这个方案。

我建议总是先进行一个初步检查,检查文件大小是否为零(或非常小),这是一个非常简单的想法:

statfile = os.stat(filename)
filesize = statfile.st_size
if filesize == 0:
  #manage here the 'faulty image' case
2

在Python中,处理这类事情的标准库就是Python图像库(PIL)

撰写回答