如何检查文件是否是有效的图像文件?

Suj*_*joy 89 python image identification imghdr

我目前正在使用PIL.

from PIL import Image
try:
    im=Image.open(filename)
    # do stuff
except IOError:
    # filename not an image file
Run Code Online (Sandbox Code Playgroud)

但是,尽管这足以涵盖大多数情况,但未检测到某些图像文件,如xcf,svg和psd.Psd文件抛出OverflowError异常.

有没有我可以包括他们?

Nad*_*mli 175

我刚刚找到了内置的imghdr模块.从python文档:

imghdr模块确定文件或字节流中包含的图像类型.

这是它的工作原理:

>>> import imghdr
>>> imghdr.what('/tmp/bass')
'gif'
Run Code Online (Sandbox Code Playgroud)

使用模块比重新实现类似功能要好得多

  • 我发现即使文件是有效图像,特别是对于 jpeg,“imghdr.what(path)”偶尔也会返回“None”。 (3认同)
  • 当心!有效的 hdr 并不意味着有效的图像(例如图像字节可能已被加扰!) (3认同)
  • 是的imghdr适用于大多数图像格式,但不是全部.根据我对svg,xcf和psd文件的原始问题,以及那些在imghdr中也未被发现的问题 (2认同)
  • 你的答案实际上更好,谢谢.就像上面说的那样*...但解决问题99%的方法往往更好,然后根本不解决它.* (2认同)
  • 值得注意的是:`imghdr.what(path)`如果给出`path`不能识别图像文件类型,则返回`None`.[列表](https://docs.python.org/3/library/imghdr.html)当前识别的图像类型:*rgb*,*gif*,*pbm*,*pgm*,*ppm*,*tiff*,*rast*,*xbm*,*jpeg*,*bmp*,*png*,*webp*,*exr*. (2认同)

Nad*_*mli 45

除了Brian建议您可以使用PIL的验证方法来检查文件是否损坏.

im.verify()

尝试确定文件是否已损坏,而不实际解码图像数据.如果此方法发现任何问题,则会引发适当的异常.此方法仅适用于新打开的图像; 如果图像已加载,则结果未定义.此外,如果需要在使用此方法后加载图像,则必须重新打开图像文件.属性

  • 我的上帝PIL文档很糟糕.什么是"合适的例外"? (15认同)
  • 嗯,源代码似乎验证了......什么也没有!https://pillow.readthedocs.io/en/latest/_modules/PIL/Image.html#Image.verify (2认同)

tsv*_*iko 17

除了PIL图像检查之外,您还可以像这样添加文件扩展名检查:

filename.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif'))
Run Code Online (Sandbox Code Playgroud)

请注意,这仅检查文件名是否具有有效的图像扩展名,它实际上并未打开图像以查看它是否为有效图像,这就是您需要额外使用PIL或其他答案中建议的库之一的原因。

  • 如果文件中的扩展名不正确怎么办?例如,文本文件以 .jpg 扩展名保存,反之亦然。 (3认同)
  • @hafiz031要获取实际格式,您可以执行`from PIL import Image img = Image.open(filename) print(img.format)`,然后像这样检查它:`img.format.lower() in ['png' , 'jpg', 'jpeg', 'tiff', 'bmp', 'gif']` (2认同)

Bri*_*ndy 10

很多时候,前几个字符将是各种文件格式的神奇数字.除了上面的异常检查之外,您还可以检查这一点.

  • 如果他真的在测试"有效"图像,这还不够; 例如,幻数的存在并不能保证文件没有被截断. (8认同)
  • @Ben Blank:是的,但解决问题99%的方法往往更好,然后根本不解决它. (6认同)

Fab*_*lao 8

更新

我还在GitHub 上的Python 脚本中实现了以下解决方案。

我还验证了损坏的文件 (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
Run Code Online (Sandbox Code Playgroud)

在图像缺陷的情况下,此代码将引发异常。请考虑 im.verify 比执行图像处理快 100 倍(我认为翻转是更便宜的转换之一)。使用此代码,您将使用标准 Pillow 以约 10 MBytes/sec 或使用 Pillow-SIMD 模块(现代 2.5Ghz x86_64 CPU)以 40 MBytes/sec 验证一组图像。

对于其他格式psd , xcf ,.. 可以使用Imagemagick包装器Wand,代码如下:

im = wand.image.Image(filename=filename)
temp = im.flip;
im.close()
Run Code Online (Sandbox Code Playgroud)

但是,根据我的实验,Wand 没有检测到截断的图像,我认为它会在没有提示的情况下将缺少的部分加载为灰色区域。

我红认为,ImageMagick的具有外部命令识别可以做的工作,但我还没有找到一种方法来编程方式调用该函数,我没有测试过这条路线。

我建议始终执行初步检查,检查文件大小不为零(或非常小),这是一个非常便宜的想法:

statfile = os.stat(filename)
filesize = statfile.st_size
if filesize == 0:
  #manage here the 'faulty image' case
Run Code Online (Sandbox Code Playgroud)


Ale*_*tin 8

一种选择是使用filetype包。

安装

python -m pip install filetype

好处

  1. 快速:是否通过仅加载图像的前几个字节来工作(检查幻数
  2. 支持不同的 mime 类型:图像、视频、字体、音频、档案。

例子

文件类型 >= 1.0.7

import filetype

filename = "/path/to/file.jpg"

if filetype.is_image(filename):
    print(f"{filename} is a valid image...")
elif filetype.is_video(filename):
    print(f"{filename} is a valid video...")
Run Code Online (Sandbox Code Playgroud)

文件类型 <= 1.0.6

import filetype

filename = "/path/to/file.jpg"

if filetype.image(filename):
    print(f"{filename} is a valid image...")
elif filetype.video(filename):
    print(f"{filename} is a valid video...")
Run Code Online (Sandbox Code Playgroud)

官方 repo 的附加信息:https : //github.com/h2non/filetype.py


fma*_*arc 7

在 Linux 上,您可以使用python-magic,它使用libmagic来识别文件格式。

AFAIK,libmagic 查看文件并试图告诉你更多关于它的信息,而不仅仅是格式,比如位图尺寸、格式版本等。所以你可能会认为这是对“有效性”的表面测试。

对于“有效”的其他定义,您可能必须编写自己的测试。


Kam*_*iel 6

您可以使用 Python 绑定到 libmagic、python-magic,然后检查 mime 类型。这不会告诉您文件是否已损坏或完整,但它应该能够确定它是什么类型的图像。