В 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
Вам также понадобится найти и настроить выборку. Для получения дополнительной информации об этой проверке здесь . Вы также можете посмотреть на test_subsampling
UPDATE
Я сделал разветвление PIL, чтобы добавить возможность указывать таблицы подвыборки или квантования или обе при сохранении JPEG. Вы также можете указать quality='keep'
при сохранении, и изображение будет сохранено с теми же таблицами квантования и подвыборки, что и оригинал (оригинал должен быть в формате JPEG). Также есть несколько предустановок (на основе Photoshop), которые вы можете передать при сохранении качества. Моя вилка.
ОБНОВЛЕНИЕ 2
Мой код теперь является частью Подушка 2.0 . Так что просто сделайте:
pip install Pillow