Сжатие растрового изображения несколько раз - PullRequest
0 голосов
/ 31 октября 2018

Android API предоставляет метод Bitmap.compress(format, quality, output) для сохранения растровых объектов. Я создал пример приложения, которое загружает изображение JPEG (некоторая фотография с шумной камерой) в растровое изображение, а затем сжимает его обратно в тот же файл. Затем делает это снова 5 раз.

Очевидно, мое растровое изображение накапливает артефакты сжатия. Удивительно для меня, количество этих артефактов странным образом зависит от качества сжатия. Когда я устанавливаю качество на 100 (что я ожидаю, чтобы быть лучшим качеством), артефакты отчетливо видны. Когда я понижаю качество до 90, артефакты становятся значительно менее заметными. Настройка качества 80 дает мне лучшие результаты. При настройке качества 70 и ниже изображение быстро ухудшается.

Когда я сжимаю растровые изображения с качеством 100, размер получаемого файла линейно увеличивается при каждом проходе. Для параметров качества 90 и 80 размер получаемого файла остается примерно одинаковым при каждом проходе.

Я протестировал это поведение на устройстве Android 5 (HTC One) и на устройстве Android 6 (Motorola Moto G), и оно было вполне последовательным. Однако на Android 7 (Samsung S7) я не заметил никакой разницы в полученных изображениях.

Итак, мой вопрос: почему сжатие с качеством = 80 дает нам лучшие результаты, чем качество = 90 и особенно качество = 100. Я действительно ожидал, что сохранение изображений с качеством 100 будет почти без потерь (как, например, в GIMP)

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Трудно сказать, не видя примеров, но я предполагаю, что артефакты, которые вы замечаете, являются высокочастотными компонентами (характеризуются резкими, крутыми изменениями яркости, которые длятся только один или два пикселя). Хотя это и не обязательно, многие алгоритмы сжатия .jpeg будут использовать конкретные матрицы квантования , которые ослабляют высокочастотные компоненты больше при ниже настройках качества, тем самым освобождая место для более низких Частота, которую вы могли бы считать более "фундаментальной" для изображения.

Итак, нетрудно представить, что при более низких настройках качества высокочастотные компоненты будут «вырезаны» из изображения, уменьшая градиенты и создавая общий «плавный» вид. И также нетрудно представить, что при высоком (но несовершенном) качестве некоторые высокочастотные компоненты могут быть преувеличены и даже усилены (из-за ошибок квантования) при последовательных прогонах.

Другими словами, макроблоки JPEG состоят из линейных комбинаций следующих примитивов 8x8, а при более низких настройках качества примитивы ближе к правому и нижнему участкам менее вероятны, поэтому: нет острых краев.

Dctjpeg.png courtesy of Wikimedia

(Исходное изображение из Викимедиа, см. Здесь )

0 голосов
/ 31 октября 2018

JPEG - это алгоритм сжатия с потерями. Даже если вы используете 100% качество, декодированное изображение не будет идентично исходному изображению. Поэтому, если вы кодируете и декодируете одно и то же изображение несколько раз, часто встречаются артефакты.

Используйте алгоритм PNG, если вы не хотите потерь.

Мой ответ является неполным, потому что 80% не должны иметь лучшее качество, чем 100%, и если это произошло в вашем случае, я не знаю, почему.

Потери не наблюдаются при кодировании с использованием Photoshop или GIMP, вероятно, потому что они улучшили алгоритм. Лучший результат в Android 7, чем в более низкой версии, также может быть результатом того же.

...