用Python确定JPG质量(PIL)

Pio*_*icz 18 python jpeg image

我正在使用Python中的PIL库,我想知道如何确定给定JPG图像的质量.我尝试打开JPG图像做一些事情,并以原始质量再次保存.Image.save让我确定所需的质量:

im.save(name, quality = x)  
Run Code Online (Sandbox Code Playgroud)

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

Eti*_*nne 26

在PIL(以及大多数使用libjpeg的软件/库)中,质量设置用于构建量化表(参考).在libjpeg中,质量数"缩放"样本表值(来自JPEG规范第K.1节).在其他图书馆中,有不同的表格分配不同的质量(例如:Photoshop,数码相机).

因此,在其他方面,质量等于量化表,因此它比一个数字更复杂.

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

这是一些保存带有指定量化表的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()))
Run Code Online (Sandbox Code Playgroud)

您需要找到从原始jpeg中提取量化表的方法.djpeg可以做到(libjpeg的一部分):

djpeg -verbose -verbose image.jpg > /dev/null
Run Code Online (Sandbox Code Playgroud)

您还需要查找和设置采样.对于该检查的详细信息在这里.你也可以看看test_subsampling

UPDATE

在保存JPEG时,我做了一个PIL fork来添加指定子采样或量化表或两者的可能性.您还可以指定quality='keep'保存时间,并使用与原始图像相同的量化表和子采样保存图像(原始图像需要为JPEG).还有一些预设(基于Photoshop),您可以在保存时传递质量.我的叉子.

更新2

我的代码现在是Pillow 2.0的一部分.所以这样做:

pip install Pillow
Run Code Online (Sandbox Code Playgroud)

  • 量化表也可以在`PIL.JpegImagePlugin.JpegImageFile`的`量化'属性中找到(这是你在`Image.open`是JPEG文件时得到的类型). (2认同)