检查图像格式是否在Python中无损?

时间:2013-02-19 01:49:32

标签: python python-imaging-library lossless-compression

我正在开发一个应用程序,要求提交给它的图像是无损的。目前我正在用PIL打开图像并检查“format”属性是否是无损格式。这需要我手动保留一个格式列表,我不知道,例如,提交的jpeg是否恰好应用了无损变体。

import PIL
import PIL.Image


def validate_image(path):
    img = PIL.Image.open(path)
    if not img.format.lower() in ['bmp', 'gif', 'png', ...]:
        raise Exception("File %s has invalid image format %s" % (path, img.format))

有没有更好的方法来检查图像文件是否无损?

1 个答案:

答案 0 :(得分:3)

我想我现在明白了:你想通过PIL打开图像。你想要拒绝有损图像,因为你正在进行某种需要丢失数据的科学处理,因为对人类视觉处理不重要的信息对你的算法很重要。

PIL在顶层没有任何类型的界面来区分不同类型的压缩。你可以到达图像解码器内部并假设任何使用“原始”解码器的东西都是无损的,但即使你想这样做,那也太有限了 - 它将排除GIF,LZW-压缩的TIFF等以及JPEG,JPEG压缩的TIFF等

请记住,真正的问题是消息传递和文档管理用户期望。检查有损图像实际上只是一种启发式方法,可以捕捉更明显的错误并提醒用户需求是什么。所以,你不需要一些完美的东西,但是有一些相当不错的东西可能会有所帮助。

所以,只有几个选项,其中没有一个非常好:

  1. 破解PIL的解码器源以保留编码信息并将其传递到顶层。显然,这将在30个不同的导入器中进行一些非平凡的工作,可能涉及C和Python,并且它将导致必须针对(缓慢)不断发展的代码库维护的补丁 - 尽管当然,你总是可以在上游提交它,并希望它能够进入PIL的未来版本。

  2. 深入解码器本身以在运行时获取信息。你真正能找到的唯一半标准的东西是它们是使用原始解码器还是位解码器,这根本没用(许多无损格式都需要位解码器),所以你最终可能会读取全部30个导入者并编写十几个代码来从中提取信息。

  3. 使用另一个库以及(或代替)PIL。例如,虽然ImageMagick肯定比PIL容易得多,但它确实有一个API来告诉你图像文件使用什么类型的压缩。基本上,如果它是UndefinedCompressionJPEGCompression它是有损的,那么其他任何东西都是无损的。主要的缺点(除了需要安装两个图像库)是PIL可以打开的文件,但IM不能,反之亦然,PIL和IM处理不同的多图像文件,等等。 / p>

  4. 做你正在做的事。通读30个进口商,列出哪些是有损的,哪些是无损的。要处理有时无损的JPEG和TIFF等情况,您可能希望编写不会完全拒绝它们的代码,而是发出警告说“这些文件可能有损。您确定要导入它们吗? “ (或者,只是提供一个“我知道我在做什么”覆盖所有有损格式,然后只考虑JPEG和TIFF有损。)

  5. 对于很多用例,我会非常谨慎地使用#4,但对于你的用户来说,它看起来非常合理。你不是要试图阻止有损图像,因为你的代码会崩溃,或出于安全原因,或类似的东西;你只是试图警告人们,如果他们提交JPEG,他们会浪费大量时间获取无用的信息,对吗?