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

时间:2009-05-20 17:55:16

标签: python image identification imghdr

我目前正在使用PIL。

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

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

有没有我可以包括它们?

11 个答案:

答案 0 :(得分:164)

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

  

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

这是它的工作原理:

>>> import imghdr
>>> imghdr.what('/tmp/bass')
'gif'

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

答案 1 :(得分:40)

除了Brian建议你可以使用PIL的verify方法来检查文件是否坏了。

  

im.verify()

     

尝试确定文件是否为   破碎,没有实际解码   图像数据。如果此方法找到任何   问题,它提出了合适的   例外。此方法仅适用于   一个新打开的图像;如果图像有   已加载,结果是   未定义。此外,如果您需要加载   使用此方法后的图像,你   必须重新打开图像文件。属性

答案 2 :(得分:9)

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

答案 3 :(得分:4)

一种选择是使用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...")

文件类型<= 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...")

有关官方仓库的其他信息:https://github.com/h2non/filetype.py

答案 4 :(得分:3)

在Linux上,您可以使用python-magic(http://pypi.python.org/pypi/python-magic/0.1)使用libmagic来识别文件格式。

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

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

答案 5 :(得分:3)

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

答案 6 :(得分:3)

除了PIL图像检查之外,您还可以添加文件扩展名检查,如下所示:

filename.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif'))

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

答案 7 :(得分:2)

好吧,我不知道psd的内部,但我确定知道,事实上,svg本身并不是一个图像文件,它基于xml,所以它是,本质上是一个纯文本文件。

答案 8 :(得分:1)

检查文件扩展名是否可以接受,或者您是否尝试确认数据本身代表图像文件?

如果您可以检查文件扩展名,则正则表达式或简单比较可以满足要求。

答案 9 :(得分:1)

更新

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

我还验证了损坏的文件(jpg)经常不是“损坏”的图像,即,损坏的图片文件有时仍是合法的图片文件,原始图像丢失或更改了,但是您仍然可以正确加载它。但是,文件截断总是导致错误。

结束更新

您可以使用具有大多数图像格式的Python Pillow (PIL)模块来检查文件是否为有效且完整的图像文件。

如果您还打算检测损坏的图像,则@Nadia Alramli正确建议使用im.verify()方法,但是此不能检测所有可能的图像缺陷,例如{{1 }}不能检测到截断的图像(大多数观看者通常会在其灰色区域加载该图像)。

枕头也能够检测到此类缺陷,但是您必须在其中应用图像处理或图像解码/重新编码或触发检查。最后,我建议使用以下代码:

im.verify

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

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

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

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

我认为 Imagemagick 具有一个外部命令 identify ,该命令可以完成任务,但是我还没有找到调用该功能的方法以编程方式,我尚未测试此路线。

我建议始终执行初步检查,检查 filesize 不为零(或很小),这是一个非常便宜的主意:

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

答案 10 :(得分:-2)

format = [".jpg",".png",".jpeg"]
 for (path,dirs,files) in os.walk(path):
     for file in files:
         if file.endswith(tuple(format)):
             print(path)
             print ("Valid",file)
         else:
             print(path)
             print("InValid",file)