Я искал способы поворота изображения без потерь и натолкнулся на этот вопрос, который довольно хорошо объясняет это:
Являются ли «Windows Photo Viewer» вращения без потерь?
Итак, я создал 256 × 256 JPEG со случайными пикселями (облачный фильтр Photoshop), а затем повернул его с помощью Windows Picture Viewer. После поворота размер файла фактически увеличился, но только при первом повороте. После каждого последующего поворота размер файла оставался неизменным. Я знаю, что он вращается без потерь, потому что я поворачивал его несколько раз без заметной потери качества, в то время как изображение 257 × 257, повернутое 20 раз, стало очень потерянным.
metadata
image-quality
jpeg
rotation
oscilatingcretin
источник
источник
Ответы:
Скорее всего, это вызвано энтропийным кодированием , которое является последней стадией сжатия JPEG без потерь после того, как данные изображения были квантованы для уменьшения его размера.
Когда изображение JPEG вращается без потерь, этот конечный уровень кодирования без потерь должен быть отменен, неупакованные коэффициенты DCT перемешиваются, а затем перемешанные коэффициенты должны быть снова подвергнуты энтропийному кодированию. Поскольку эффективность уровня энтропийного кодирования зависит от порядка коэффициентов DCT в каждом блоке, который будет изменять поворот изображения, не должно быть удивительным, что файл повернутого изображения может быть на несколько процентов меньше или больше исходного.
Существует также несколько различных способов выполнения этапа энтропийного кодирования, поэтому вполне возможно, что размер файла точно такого же изображения JPEG может варьироваться в зависимости от программного обеспечения, выполняющего кодирование. Некоторые из потенциальных различий между кодерами включают в себя:
Кроме того, «файлы JPEG», с которыми обычно работают люди, на самом деле содержат сжатые JPEG-данные изображения, заключенные в JFIF или контейнер Exif , который объединяет данные изображения с одним или несколькими блоками метаданных и вносит свой собственный набор сложностей. Даже если программное обеспечение, которое вращает изображение, на самом деле не вносит каких-либо существенных изменений в метаданные JFIF / Exif, простая перегруппировка данных может потенциально повлиять на размер файла на несколько байтов.
В частности, метаданные JFIF / Exif могут содержать одну или несколько миниатюр полноразмерного изображения, и программное обеспечение, которое вращает изображения, действительно должно восстанавливать (или также вращать без потерь!) Миниатюры, чтобы они соответствовали новой ориентации полноразмерного изображения. размер изображения. Одно это может легко объяснить наблюдаемую разницу в размерах.
источник
Я продолжил и повторил эксперимент, чтобы посмотреть, смогу ли я понять, что происходит.
Процедура
Я сгенерировал случайное RGB-изображение размером 256 на 256 пикселей, используя фильтр «Solid Noise» в GIMP («Фильтры»> «Рендеринг> Облака> Solid Noise ...») с настройками по умолчанию (показано ниже):
И результат:
Затем я сохранил изображение в формате JPEG, используя настройки по умолчанию:
Затем я перенес изображение в Windows и открыл его с помощью средства просмотра фотографий Windows, щелкнув правой кнопкой мыши изображение в проводнике и выбрав в меню « Просмотр» . Затем я повернул изображение с помощью кнопок внизу и сохранил изображение, перейдя к следующему изображению с помощью клавиш со стрелками.
Для каждого из приведенных ниже тестов я начал с копии исходного изображения и повернул (щелкнул по кнопке поворота) соответствующее количество раз перед сохранением. Вот остальные размеры (
ls -l -r
):Немедленные наблюдения
Использование
cmp -l
файлов, которые должны иметь идентичный контент, позволяет нам увидеть, где файлы отличаются.Эти файлы отличаются только четырьмя байтами (на самом деле это временная метка), что означает, что WPV каждый раз делает одно и то же; теперь нам нужно только выяснить, что это такое.
Подробные наблюдения
Для этого я использовал JPEGsnoop, чтобы увидеть, что именно было на изображениях.
Поскольку результаты довольно длинные, я привел их в качестве сути . Вот краткое изложение различий:
GIMP использует только
APP0
(JFIF) иCOM
(комментарий) сегмент для метаданных. WPV оставляетAPP0
сегмент нетронутым, но, как ни странно, добавляет к комментарию нулевой байт (так что он завершается нулем).WPV добавляет два
APP1
сегмента, которые являются метаданными Exif и XMP. Эти сегменты составляют 4286 и 12726 байт соответственно. Вместе они составляют почти все увеличение размера файла.GIMP создает прогрессивный JPEG, а WPV - базовый (не прогрессивный) JPEG. По этой причине изображение GIMP имеет несколько сегментов сканирования, а изображение WPV - только один. По моему опыту, прогрессивное изображение иногда немного меньше.
GIMP использовал 1 × 1 цветовой подвыборки, в то время как WPV использовал 2 × 2 подвыборки. Это наводит меня на мысль, что WPV не использует «истинное» вращение без потерь, если только оно каким-то образом не способно обнаружить это черно-белое изображение.
Чтобы решить эти проблемы, я провел второй тест.
Процедура
Я выполнил шаги, аналогичные первому тесту. Я создал случайное изображение RGB 256 × 256, используя фильтр шума RGB (Фильтры> Нос> Нос RGB ...) со следующими настройками:
Вот результат:
Я экспортировал файл в формате JPEG с использованием следующих настроек:
Прогрессивный режим отключен, но для субсэмплинга по-прежнему установлено значение 4: 4: 4 (другое название для субсэмплинга 1 × 1). Качество увеличено до 98.
Я скопировал изображение и повернул копию по часовой стрелке; затем скопировали повернутую версию и повернули эту копию против часовой стрелки, чтобы мы могли напрямую сравнить качество между оригинальной и обработанной копией WPV.
Полученные результаты
Хотя это увеличение меньше в относительном выражении (около 40%), абсолютное увеличение еще больше - около 62 кБ. Это говорит о том, что WMV использует менее эффективную кодировку.
Я буду использовать ImageMagick для сравнения двух изображений:
Есть ноль пикселей разные между оригиналом и копией повернутой. Таким образом, даже если WPV не использует «истинное» вращение без потерь, оно работает достаточно хорошо. Я подозреваю, что знаю, что происходит, и, чтобы объяснить, я немного углублюсь в математику сжатия JPEG.
Алгоритм сжатия JPEG разбивает изображение на блоки 8 × 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 × 1, поэтому он может фактически обнаружить, что это цветное изображение (или, по крайней мере, что более высокие выборки необходимы для перекодирования изображения без потерь).
GIMP и WPV используют разные таблицы Хаффмана (часть этапа энтропийного кодирования). Таблицы для WPV больше на 279 байтов и в одном случае содержат в 7 раз больше кодов.
Глядя на статистику JPEGsnoop, мы видим, что некоторые из этих кодов используются редко. Например, в
ID: 1, Class: AC
таблице из 119 определенных 16-битных кодов фактически используются только 23. В целом, фактический сегмент сканирования в версии WPV на 28,5% больше.Резюме
WPV, возможно, не делает «настоящих» вращений без потерь, но вращения кажутся практически без потерь.
Дополнительный размер частично обусловлен фиксированным количеством добавленных метаданных, а частично - менее эффективным энтропийным кодированием.
Информация о версии:
ОС (Linux) (
uname -a
):ОС (Windows):
GIMP (Linux): 2.8.14 (из пакета
gimp
, версии2.8.14-1+deb8u1
)Окно просмотра фотографий (в соответствии с метаданными изображения):
источник
РЕДАКТИРОВАТЬ : Этот ответ был опубликован до того, как я узнал, что размер файлов увеличился примерно на 9 КиБ (9055 байт для изображения 256 × 256, 9612 КиБ для изображения 512 × 512).
По всей вероятности, когда вы впервые повернули изображение, Windows Picture Viewer сделал одну (или обе) из следующих вещей:
Это увеличило размер файла из-за дополнительного тега EXIF (и / или дополнительных данных к существующим тегам).
Последующие ротации не увеличивали размер файла, потому что все теги и / или данные тегов, которые WPV добавил бы / изменил, уже были там. Изменено только значение тега ориентации (и, возможно, значения тега даты / времени).
РЕДАКТИРОВАТЬ : Почти наверняка, что это объяснение не может содержать около 9 КиБ дополнительных данных в файле. Кроме того, в отсутствие каких-либо других причин увеличения размера это объяснение предполагает, что увеличение размера будет более или менее постоянным (по модулю некоторых различий в длине между строковыми представлениями числовых данных, возможно, в несколько байтов). Это, очевидно, не то, что здесь происходит, по крайней мере, не полное объяснение.
источник
Без обратного инжиниринга jpeg en / decoder невозможно сказать наверняка. На самом деле существует ряд стандартов jpeg, и вопреки распространенному мнению, не все они могут быть изменены без перекодирования.
Вполне возможно, что первое сохранение - это перезапись с потерями в его предпочтительный формат jpeg, а последующие вращения - это простая настройка метаданных или операция непосредственно над таблицей DCT (что возможно для некоторых схем кодирования).
Увеличение размера файла может также включать некоторые дополнительные метаданные, хотя 9k кажется большим, это возможно. Увеличение также может быть объяснено добавлением миниатюры, которая может отсутствовать в выходных данных GIMP. Мы можем получить больше информации из файлов напрямую (до WPV и после).
В любом случае, пытаться без потерь работать с jpeg - это действительно дурацкое поручение, так как это полезно только для изображений определенного размера, не все декодеры и кодеры идентичны, и это требует, чтобы эти редакторы работали напрямую с содержимым jpeg, на которое нельзя полагаться. дело ... То, что это происходит сейчас, не означает, что так будет и в будущем.
Лучше всего работать с форматом без потерь и полностью избежать боли.
источник
Вращение JPEG без потерь возможно только без введения граничных артефактов, если размеры изображения кратны размеру блока (обычно [/ всегда?] 8). См. Справочную страницу jpegtran (извините, у меня нет хорошей канонической ссылки для нее; не стесняйтесь редактировать, если вы ее найдете), чтобы узнать подробности:
Я подозреваю, что Windows Photo Viewer избегает этой проблемы, выполняя декомпрессию и чрезвычайно высококачественную рекомпрессию для имитации поведения без потерь, когда размеры изображения не кратны 8, вместо того, чтобы фактически выполнять вращение без потерь. Хорошая утилита просто делала бы реальные потери без потерь, артефакты и все, или сбрасывала несколько пикселей, вместо того, чтобы ухудшать качество всего изображения (и увеличивать размер файла).
источник
У меня нет определенного ответа, но есть несколько возможных теорий, почему это произошло. Некоторые типы файлов работают таким образом, что два разных кода для изображения этого типа файла не обязательно создают разные изображения. Например, тип файла PNG работает таким образом, потому что он допускает прозрачный фон, но изображение с прозрачным фоном и одно и то же, за исключением того, что один и тот же фон белого цвета, выглядит точно так же. Файл изображения считается сжатым, если он занимает менее 3 байтов памяти на пиксель. Я считаю, что кроме тех, которые имеют прозрачный фон, никакие два файла PNG не генерируют точно такое же изображение. Когда вы сохраняете изображение в формате PNG, оно преобразует его в код, который генерирует исходное изображение, за исключением очень необычных изображений, таких как одно, где каждый пиксель является случайным цветом всех 2 ^ 24 цветов, код будет занимать меньше памяти, чем 3 байта на пиксель, поэтому сохранение, поскольку PNG называется сжатием без потерь. С другой стороны, для экономии памяти с помощью кода файла изображения JPEG можно генерировать только определенные изображения. Вероятно, существует несколько типов файлов JPEG, и я не знаю, обладает ли какой-либо из них свойством, что два разных изображения этого типа файлов могут генерировать одно и то же изображение. Я предполагаю, что несколько раз вы просто поворачивали изображение, а затем сохраняли его в формате JPEG и объяснили, что произошло, исходя из предположения, что это то, что вы сделали, и я не знаю, правда ли это. Вращение, которое вы сделали, без потерь, если есть способ вернуть тот же код файла изображения, который вы использовали до того, как повернули и сохранили его. Возможно, вы не правы, что вы действительно сделали вращение без потерь. Если бы это действительно было без потерь,
источник
Причины этого несколько
способ кодирования и сжатия изображений изменит размер просто из-за алгоритма сжатия. Вы можете проверить это, сохранив его как растровое изображение, а затем повернув его. В этом формате или в любом необработанном формате размер должен оставаться прежним. Если этого не происходит, программа, сохраняющая изображение, добавляет новые данные, возможно, некоторые метаданные или что-то в этом роде.
Но почему вы вращаете JPEG в 20 раз?
источник
Из-за того, как работает сжатие изображений . Любой формат, такой как PNG или JPG в целом, не сохраняет размер файла после поворота.
Для компрессора повернутое изображение - это просто другое изображение, так как эвристика сжатия работает , нет гарантии, что оно будет сжимать повернутое изображение так же .
Конечно, если сжатие выполняется без потерь, если вы поворачиваете изображение 4 раза в 4-й раз, изображение снова становится таким же (поворачивается до тех пор, пока оно не станет наклоненным как оригинал): в этом случае оно должно снова стать таким же сжатым размером, если нет, то это из-за одной из следующих причин :
Сжатие изображений работает путем сжатия изображений в фрагменты 4x4 или других размеров. В общем, компрессор видит повернутое изображение как другое изображение, однако, поскольку сжатый пиксельный фрагмент представляет собой просто линейную декомпозицию, если фрагменты на изображении одинаковы, можно просто транспонировать / отразить матрицы линейной декомпозиции, эффективно сохраняя их качественный:
Обратите внимание, что это должно быть реализовано отдельно для каждого объекта , и это также объясняет начальное увеличение размера => при первом повороте, оно просто пытается сжать изображение фрагментами, которые могут вращаться:
Если он успешен, он увеличивает размер только один раз, тогда каждое вращение сохраняет то же качество.
Эта операция будет успешной, только если изображение составлено равными частями. (размер изображения кратен размеру фрагмента).
Скоттбб ответит неправильно, и вы можете сделать простой тест:
Вы увидите измененное изображение (оно сжимается при первом повороте). Однако это изменение ограничено по времени, теперь вы можете повернуть его снова без потери качества (если размер изображения кратен 8)
Чтобы напрямую ответить на OP:
Он не вращается без потерь, он теряет качество хотя бы один раз (при первом вращении: поскольку он должен сначала сжать его таким образом, чтобы его можно было вращать), затем он сохраняет свое качество.
источник
<?xpacket
тегах.