我正在玩Python中的PIL库,并且想知道如何确定给定JPG图像的质量。我尝试打开JPG图像并对其进行处理,然后以其原始质量再次保存。 Image.save让我确定所需的质量:

im.save(name, quality = x)

但我看不出有任何方法可以提取原始内容。现在,我只是在猜测,并通过对'quality'参数进行二进制搜索来尝试具有与输入大小相同的输出文件,但这是不能接受的长期解决方案:)
我也尝试使用:Image.info,但是我的大多数图像那里没有任何有用的信息(例如:“adobe”,“icc_profile”,“exif”,“adobe_transform”)
帮助 !

最佳答案

在PIL(以及大多数使用libjpeg的所有软件/库)中,质量设置用于构造量化表(ref.)。在libjpeg中,质量编号“缩放”样本表值(来自JPEG规范K.1节)。在其他类别中,有不同的表分配给不同的质量(例如:Photoshop,数码相机)。

因此,换句话说,质量等于量化表,因此它比数字更复杂。

如果要以相同的“质量”保存修改图像,则只需使用相同的量化表。幸运的是,量化表被嵌入到每个JPEG中。不幸的是,在保存为PIL时无法指定量化表。 libjpeg附带的命令行实用程序cjpeg可以做到这一点。

这是一些用指定的量化表保存jpeg的粗略代码:

from subprocess import Popen, PIPE
from PIL import Image, ImageFilter

proc = Popen('%s -sample 1x1 -optimize -progressive -qtables %s -outfile %s' % ('path/to/cjpeg', '/path/ta/qtable', 'out.jpg'), shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
P = '6'
if im.mode == 'L':
    P = '5'
stdout, stderr = proc.communicate('P%s\n%s %s\n255\n%s' % (P, im.size[0], im.size[1], im.tostring()))

您将需要找到从原始jpeg提取量化表的方法。 djpeg可以做到这一点(libjpeg的一部分):
djpeg -verbose -verbose image.jpg > /dev/null

您还需要查找并设置采样。有关更多信息,请检查here。您也可以看看 test_subsampling

更新

我做了一个PIL分支,以添加在保存JPEG时指定子采样表或量化表或同时指定两者的可能性。您还可以在保存时指定quality='keep',图像将使用与原始图像相同的量化表和二次采样(原始图像必须为JPEG)进行保存。保存时还有一些预设(基于Photoshop)可以传递给质量。 My fork.

更新2

我的代码现在是Pillow 2.0的一部分。所以做:
pip install Pillow

关于python - 确定Python(PIL)中的JPG质量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4354543/

10-12 21:52