Я продолжил и повторил эксперимент, чтобы посмотреть, смогу ли я понять, что происходит.
Процедура
Я сгенерировал случайное RGB-изображение размером 256 на 256 пикселей, используя фильтр «Solid Noise» в GIMP («Фильтры»> «Рендеринг> Облака> Solid Noise ...») с использованием настроек по умолчанию (показано ниже):
![enter image description here](https://i.stack.imgur.com/ogvYL.png)
И результат:
![enter image description here](https://i.stack.imgur.com/UbdvJ.jpg)
Затем я сохранил изображение в формате JPEG, используя настройки по умолчанию:
![enter image description here](https://i.stack.imgur.com/DgKKw.png)
Затем я перенес изображение в Windows и открыл его с помощью Windows Photo Viewer, щелкнув правой кнопкой мыши изображение в проводнике и выбрав Preview в меню. Затем я повернул изображение с помощью кнопок внизу и сохранил изображение, перейдя к следующему изображению с помощью клавиш со стрелками.
Для каждого из приведенных ниже тестов я начинал с копии исходного изображения и поворачивал (нажимал на кнопку поворота) соответствующее количество раз перед сохранением. Вот остальные размеры (ls -l -r
):
size in bytes last-modified date
VVVVV VVVVV
-rwxrwx--- 1 root vboxsf 6258 Nov 8 11:24 original.jpg
-rwxrwx--- 1 root vboxsf 23645 Nov 8 11:30 cw.jpg
-rwxrwx--- 1 root vboxsf 23636 Nov 8 11:30 cw-cw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:30 cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf 6258 Nov 8 11:27 cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:31 cw-cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:29 ccw.jpg
-rwxrwx--- 1 root vboxsf 23636 Nov 8 11:29 ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf 23645 Nov 8 11:29 ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf 6258 Nov 8 11:27 ccw-ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:30 ccw-ccw-ccw-ccw-ccw.jpg
Немедленные наблюдения
- Windows Photo Viewer (WPV) действительно значительно увеличивает размер; величина увеличения в этом тесте примерно в четыре раза!
- Все новые изображения увеличиваются примерно до одинакового размера, но они не идентичны.
- WPV не перекодирует и даже не повторно сохраняет изображение, когда оно поворачивается на 360 градусов. (Отметка времени 11:27 - это время, когда файлы были впервые скопированы.)
Использование cmp -l
для файлов, которые должны иметь идентичное содержимое, позволяет нам увидеть, где файлы различаются.
robert@unity ../jpeg-rotate-test % cmp -l cw.jpg ccw-ccw-ccw.jpg
2223 63 62
2224 60 71
2226 60 64
2227 60 66
robert@unity ../jpeg-rotate-test % cmp -l cw-cw.jpg ccw-ccw.jpg
2223 63 62
2224 60 71
2226 60 64
2227 62 64
robert@unity ..jpeg-rotate-test % cmp -l ccw.jpg cw-cw-cw.jpg
2223 62 63
2224 71 60
2226 64 60
2227 61 64
robert@unity ../jpeg-rotate-test % cmp -l cw.jpg cw-cw-cw-cw-cw.jpg
2221 60 61
2223 63 61
2224 60 66
2226 60 61
2227 60 61
robert@unity ../jpeg-rotate-test % cmp -l ccw.jpg ccw-ccw-ccw-ccw-ccw.jpg
2223 62 63
2224 71 60
2226 64 65
2227 61 64
Эти файлы отличаются только четырьмя байтами (фактически, отметкой времени), что означает, что WPV каждый раз делает одно и то же; теперь нам нужно только выяснить, что это такое.
Подробные наблюдения
Для этого я использовал JPEGsnoop , чтобы увидеть, что именно было на изображениях.
Поскольку выходы довольно длинные, я связал их с сущностью . Вот краткое изложение различий:
GIMP использует только сегменты APP0
(JFIF) и COM
(комментарий) для метаданных. WPV оставляет сегмент APP0
нетронутым, но с любопытством добавляет нулевой байт к комментарию (так что он заканчивается нулем).
WPV добавляет два APP1
сегмента, которые являются метаданными Exif и XMP. Эти сегменты составляют 4286 и 12726 байт соответственно. Вместе они составляют почти все увеличение размера файла.
GIMP создает прогрессивный JPEG, а WPV - базовый (не прогрессивный) JPEG. По этой причине изображение GIMP имеет несколько сегментов сканирования, а изображение WPV - только один. По моему опыту, прогрессивное изображение иногда немного меньше.
GIMP использовал 1 & times; 1 подвыборку цветности, в то время как WPV использовал 2 & times; 2 подвыборки. Это заставляет меня поверить, что WPV не использует «истинное» вращение без потерь, если только оно каким-то образом не может обнаружить это черно-белое изображение.
Чтобы решить эти проблемы, я провел второй тест.
Процедура
Я следовал шагам, подобным первому тесту. Я создал случайное изображение 256 & times; 256 RGB, используя фильтр шума RGB (Фильтры> Нос> Нос RGB ...) со следующими настройками:
![enter image description here](https://i.stack.imgur.com/pABEB.png)
Вот результат:
![enter image description here](https://i.stack.imgur.com/2MftH.jpg)
Я экспортировал файл в формате JPEG, используя следующие настройки:
![enter image description here](https://i.stack.imgur.com/RRIT2.png)
Прогрессивный был отключен, но Субсэмплинг все еще установлен на 4: 4: 4 (что является еще одним именем для 1 & times; 1 субсэмплинг). Качество увеличено до 98.
Я скопировал изображение и повернул копию по часовой стрелке; затем скопировали повернутую версию и повернули эту копию против часовой стрелки, чтобы мы могли напрямую сравнить качество оригинала и обработанной копии WPV.
Результаты
-rwxrwx--- 1 root vboxsf 159774 Nov 8 16:21 original-random.jpg
-rwxrwx--- 1 root vboxsf 222404 Nov 8 16:24 cw-random.jpg
-rwxrwx--- 1 root vboxsf 222467 Nov 8 16:24 cw-ccw-random.jpg
Хотя увеличение на этот раз меньше в относительном выражении (около 40%), абсолютное увеличение еще больше - около 62 кБ. Это говорит о том, что WMV использует менее эффективную кодировку.
Я буду использовать ImageMagick для сравнения двух изображений:
robert@unity ../jpeg-rotate-test % compare -verbose -metric AE original-random.jpg cw-ccw-random.jpg null:
original-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 160KB 0.000u 0:00.009
cw-ccw-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 222KB 0.010u 0:00.010
Image: original-random.jpg
Channel distortion: AE
red: 0
green: 0
blue: 0
all: 0
original-random.jpg=> JPEG 256x256 256x256+0+0 8-bit sRGB 0.050u 0:00.020
* * * * * * * * между оригиналом и повернутой копией ноль пикселей различны . Таким образом, даже если WPV не использует «истинное» вращение без потерь, оно работает достаточно хорошо. Я подозреваю, что знаю, что происходит, и для объяснения я немного углублюсь в математику сжатия JPEG.
Алгоритм сжатия JPEG разбивает изображение на 8 & times; 8-пиксельные блоки. Каждый из этих блоков затем подвергается дискретному косинусному преобразованию (DCT) . Результирующие коэффициенты DCT описывают блок как сумму волн различной частоты. Затем алгоритм «выбрасывает» в высокочастотные волны некоторую информацию, соответствующую шуму и очень мелким деталям. Процесс декодирования инвертирует DCT, складывая сохраненные волны вместе, чтобы вернуть блок.
Можно вращать «волны» DCT, фактически не отменяя и не переделывая преобразование (в основном вы превращаете все горизонтальные волны в вертикальные волны и наоборот). Я думаю, что в WPV происходит то, что изображение фактически декодируется, поворачивается, а затем перекодируется. Во время процесса перекодирования, поскольку размер нашего изображения кратен 8 в обоих измерениях, каждый из новых блоков соответствует одному из исходных блоков. Важно отметить, что поскольку в каждом блоке нет высокочастотных компонентов, алгоритм не выбрасывает какую-либо информацию и находит именно те компоненты DCT, которые имел бы «истинный» поворот без потерь.
Наконец, я еще раз посмотрю на компоненты файлов JPEG. Результаты снова связаны как суть . Сравнивая два:
Образ WPV содержит дополнительные 4286 + 2 байта метаданных Exif, 1 дополнительный байт в комментарии и 12 726 + 2 байта метаданных XMP. Это всего 17 017 байтов дополнительных метаданных. Для чего используются все эти данные? Я заглянул в файл с моим верным шестнадцатеричным редактором и копией соответствующих стандартов:
Метаданные Exif структурированы как изображение TIFF, которое содержит несколько тегов (есть способ более сложный, но я пропущу его сразу). Большинство байтов в сегменте Exif содержатся в двух одинаковых тегах с номером тега EA1C
(59 932 десятичных). Этот номер тега нигде не задокументирован. Оба тега содержат 2060 байтов типа «неопределенный», которые являются нулевыми байтами, кроме первых шести (1C EA 00 00 00 08
). Я понятия не имею, что это за теги, почему их два, и почему они должны иметь размер 2 КБ каждый.
Метаданные XMP на самом деле представляют собой весь встроенный XML-документ с пространством имен и длинными UUID, который просто содержит строку версии WPV (которая уже была в метаданных Exif). Тем не менее, это только около 400 байтов. Остальная часть сегмента - это 122 повторения из 100 пробелов, за которыми следует новая строка . Это более 12 000 байт полностью потерянного пространства.
Как и в предыдущем тесте, и GIMP, и WPV используют одни и те же таблицы квантования DCT. Это означает, что они должны вычислять точно такие же коэффициенты DCT, поэтому изображения точно такие же. Я не уверен, что WPV просто использует те же таблицы квантования или копирует таблицы из входных данных.
В отличие от предыдущего теста, в этот раз WPV использует 1 & times; 1 субсэмплинг, поэтому он может на самом деле обнаруживать, что это цветное изображение (или, по крайней мере, более высокие выборки необходимы для перекодирования изображения без потерь).
GIMP и WPV используют разные таблицы Хаффмана (часть этапа энтропийного кодирования). Таблицы для WPV больше на 279 байтов и в одном случае содержат в 7 раз больше кодов.
Глядя на статистику JPEGsnoop, мы видим, что некоторые из этих кодов используются редко. Например, в таблице ID: 1, Class: AC
из 119 определенных 16-битных кодов фактически используются только 23. В целом, фактический сегмент сканирования в версии WPV на 28,5% больше.
Резюме
WPV, возможно, не выполняет "настоящих" вращений без потерь, но вращения, по-видимому, практически без потерь.
Дополнительный размер частично обусловлен фиксированным количеством добавленных метаданных, а частично - менее эффективным энтропийным кодированием.
Информация о версии:
ОС (Linux) (uname -a
):
Linux unity 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux
ОС (Windows):
![enter image description here](https://i.stack.imgur.com/o6BLG.png)
GIMP (Linux): 2.8.14 (из пакета gimp
, версия 2.8.14-1+deb8u1
)
![enter image description here](https://i.stack.imgur.com/uIabl.png)
Окно просмотра фотографий (в соответствии с метаданными изображения):
Microsoft Windows Photo Viewer 10.0.10586.0