2010-12-04 52 views
13

我正在玩Python中的PIL庫,我想知道如何確定給定JPG圖像的質量。我試圖打開JPG圖像做一些事情,並保存在原來的質量。 Image.save讓我確定所需的質量:在Python中確定JPG質量(PIL)

im.save(name, quality = x) 

但我看不到任何方法來提取原始的。現在我只是猜測,並嘗試通過在'質量'參數上進行二分搜索來獲得與輸入大小相同的輸出文件,但這是不可接受的長期解決方案:)
我也試過使用:Image.info,但大多數我的圖片沒有任何有用的信息(例如:'adobe','icc_profile','exif','adobe_transform')
幫助!

+1

相關信息:http://superuser.com/questions/62730/how-to-find-the-jpg-quality/91083#91083 – unutbu 2010-12-04 16:54:30

+0

一般來說,是不可能恢復的精確用於壓縮JPEG文件的質量值,因爲存在各種不同的減少存儲信息的方式,而質量值僅僅是編碼器的指南,但正如@unutbu指出的那樣,某些軟件可以做出英雄式的猜測。 – andrewmu 2010-12-04 17:00:19

+1

可能值得一提的是,JPEG是一種有損格式,因此即使「質量」選項設置爲相同值,打開和保存圖像也會降低圖像質量。 – 2011-01-12 12:20:14

回答

22

在PIL(以及大多數使用libjpeg的軟件/庫)中,質量設置用於構建量化表(ref.)。在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())) 

你需要找到從原單JPEG提取量化表的方式。djpeg可以做到這一點(的libjpeg的一部分):

djpeg -verbose -verbose image.jpg > /dev/null 

,您還需要找到並設置採樣。有關檢查here的更多信息。您還可以看看test_subsampling

UPDATE

我做了一個PIL叉添加到指定子採樣或量化表或保存JPEG當兩個可能性。保存時您還可以指定quality='keep',圖像將使用與原始圖像相同的量化表和子採樣進行保存(原始圖像需要爲JPEG)。還有一些預設(基於Photoshop),您可以在保存時傳遞質量。 My fork.

更新2

我的代碼是現在的Pillow 2.0一部分。所以只是做:

pip install Pillow 
-3

據我瞭解你,這是不可能的。 JPEG格式通過移除75%的顏色數據或通過簡化顏色來壓縮。沒有辦法使顏色質量更高。

4

質量是用來生成存儲在JPEG中的數據的東西。該號碼不存儲在JPEG中。

您可能能夠確定質量的一種方法是在對圖像進行編輯並運行JPEG壓縮公式之前,先採用圖像的8x8像素單元格,以便接近原始圖像。您需要根據其結果開發一個距離函數(原始像素差異)。

您仍然在進行具有質量的二進制搜索,但它的工作量要少得多。

這裏是一個如何JPEG壓縮從MS FAQ

工作

http://www.dspguide.com/ch27/6.htm

這裏的另一種方式

http://support.microsoft.com/kb/324790

你必須從C#翻譯信息。