132

我目前正在使用 PIL。

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

然而,虽然这足以涵盖大多数情况,但某些图像文件(如 xcf、svg 和 psd)并未被检测到。Psd 文件会引发 OverflowError 异常。

有什么办法我也可以包括它们吗?

4

9 回答 9

238

我刚刚找到了内置的imghdr模块。来自 python 文档:

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

这是它的工作原理:

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

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

于 2009-05-24T00:29:03.123 回答
54

除了 Brian 建议的内容之外,您还可以使用 PIL 的验证方法来检查文件是否损坏。

im.verify()

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

于 2009-05-20T19:02:45.300 回答
19

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

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

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

于 2019-08-08T09:26:22.707 回答
17

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

于 2009-05-20T17:58:26.133 回答
10

一种选择是使用该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

于 2020-04-13T19:23:06.023 回答
9

更新

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

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

结束更新

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

如果您还打算检测损坏的图像,@Nadia Alramli 会正确建议该im.verify()方法,但这并不能检测到所有可能的图像缺陷,例如,im.verify不会检测到截断的图像(大多数查看器通常加载灰色区域)。

Pillow也能够检测到这些类型的缺陷,但您必须应用图像处理或图像解码/重新编码或触发检查。最后我建议使用这段代码:

from PIL import Image

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(Image.FLIP_LEFT_RIGHT)
  im.close()
except: 
  #manage excetions here

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

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

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

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

我认为Imagemagick有一个外部命令identify可以完成这项工作,但我还没有找到以编程方式调用该函数的方法,我也没有测试过这条路线。

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

import os

statfile = os.stat(filename)
filesize = statfile.st_size
if filesize == 0:
  #manage here the 'faulty image' case
于 2018-11-25T19:03:07.600 回答
7

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

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

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

于 2009-05-20T18:05:40.487 回答
6

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

于 2009-05-20T19:29:00.193 回答
-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)
于 2020-02-26T09:30:35.523 回答