читать дальше »
Оптимизация JPEG: сжатие без потерь Определимся со стоящей перед нами задачей: сжать предназначенный для публикации в интернете JPEG (JPG) файл без потери качества. Для начала разберёмся, за счёт чего мы вообще можем сжать и без того сжатый файл? Ведь всем известно, что JPEG-файл почти невозможно компрессировать обычными арифметическими алгоритмами, такими как ZIP или RAR. Существуют три способа: Применить другой способ энтропийного кодирования (прогрессивного арифметического сжатия). Удалить всю лишнюю метаинформацию (EXIF, комментарии, ICC-профили). Удалить вшитый в файл эскиз (thumbnail) - уменьшенную копию изображения. Можно применить каждый способ по-отдельности, а можно и все вместе. Вот только встроенный эскиз является составной частью EXIF, а значит при удалении метаданных удаляется и он сам. После длительного изучения различных инструментов, выбор остановился на двух, наиболее качественных и функциональных программах: jpegtran и jhead. Их можно установить и использовать как в Linux, так и в Windows. Первая утилита входит в библиотеку libjpeg - набор программ, разработанные Independent JPEG Group и предназначенные для работы с JPEG-изображениями. В частности, jpegtran позволяет выполнять ряд операций над jpg-файлом без потери качества. Вторая программа, jhead - это разработка канадского парня Матиаса Уандела (Matthias Wandel), с помощью которой мы сможем работать с метаинформацией, зашитой в JPEG-файлы. Для эксперимента были взяты два различающихся набора файлов. Первый - это мой личный каталог images, в котором собрано большое количество совершенно различных JPEG-файлов. Разных размеров, происхождения и типов. В общем, это не однотипные фотографии одного фотоаппарата. Суммарный размер - 52 Мб. Файлов 132 штуки. Средний размер файла - 390 Кб. Второй набор - собрание фотографий одного из сайта, поддерживаемых мной. 804 штуки общим размером 43 Мб. То есть, 53 Кб на одно фото, в среднем. Перекодировать будем следующим образом.
Только перекодирование, с сохранением EXIF и эскиза:
for i in *;
do jpegtran -optimize -progressive -copy all -outfile "with_exif/$i" "$i";
done
Перекодирование без сохранения EXIF:
for i in *;
do jpegtran -optimize -progressive -outfile "without_exif/$i" "$i";
done
Удалим эскизы, но сохраним EXIF в перекодированных файлах:
do jhead -dt *
Хорошо, перейдём к делу.
Перекодируем JPEG-файлы первого тестового набора - каталога images.
$ du -s originals/ exif/ without_thumb/ without_exif/
52508 originals/
49280 exif/
48892 without_thumb/
48588 without_exif/
Таким образом, если мы удалим вообще всю EXIF-информацию, то общий размер уменьшается на 5 Мб. Что довольно неплохо. Если оставить всё, даже EXIF с thumbnail-ами, то мы всё равно выигрываем 4 Мб. На ровном месте, без потери качества. Неплохо? Вполне. А теперь посмотрим дальше.
Теперь, в качестве тестового набора фотографий, возьмём фотоколлекцию сайта.
$ du -s photo exif without_thumb without_exif
43288 photo
26536 exif
24520 without_thumb
23900 without_exif
Впечатляет! Простейшим перекодированием мы получаем сжатие почти в два раза! В это трудно поверить, но подвоха я не нашёл. А если ещё удалить EXIF, то мы выйграем дополнительные 3 Мб на 804 файла.
А теперь нужно разобраться, нужны ли нам EXIF-метатеги?
В них содержится такая важная информация, как параметры, дата и, возможно, координаты места съёмки. Когда фотографий становится несколько тысяч - это существенное подспорье для организации каталога и поиска по нему. Поэтому безусловно, они крайне нужны для организации каталога фотографий.
Ну, а в интернете? Неужели посетитель будет смотреть каким фотоаппаратом и с какой выдержкой и диафрагмой автор делал свою фотографию? Сомневаюсь.
Последняя надежда на секцию Comment метаданных фотографии, в которую мы можем вписать ключевые слова фотографии и имя автора для указания копирайта. Но, обращают ли внимание на эту секцию поисковые системы? Утвердительного ответа на этот вопрос я так и не нашёл.
И последнее.
Чтобы убедиться в том, что после всех этих преобразований, изображение осталось нетронутым, относительно оригинала, произведём следующие операции.
С помощью программы djpeg, из поставки libjpeg, декодируем JPEG-файл в формат RAW:
$ djpeg noexif.jpg > noexif.raw
$ djpeg origin.jpg > origin.raw
И определим, совпадают ли оба RAW-файла побайтово:
$ md5sum *.raw
6deb36a0b017cc7c41025e7a24e8f30e noexif.raw
6deb36a0b017cc7c41025e7a24e8f30e origin.raw
Как видим, содержимое файлов идентично, а значит, не было утрачено ни единого бита графической информации и с исходной задачей мы справились.
Вот к нему фак только на энглише.