Два ТОЧНО одинаковых изображения .jpg, одно из которых более чем в два раза превышает размер другого. Почему?

У меня есть несколько изображений .jpg, которые ТОЧНО (точек на дюйм, размер кадра, изображение) одинаковы, за исключением того, что размер одного файла более чем в два раза превышает размер другого (в байтах). Как это может быть? Когда я увеличиваю масштаб, скажем, на 700% в одном и том же месте на каждом изображении, я вижу примерно одинаковое количество пикселей, что указывает на то, что сжатие одинаково.

На основании каких доказательств вы утверждаете, что два файла абсолютно одинаковы - визуальное сравнение или реальное попиксельное сравнение с использованием чего-то вроде сравнения ImageMagick? Два изображения на самом деле могут выглядеть очень похожими визуально, но в то же время совершенно разными. Другими факторами могут быть уровни сжатия, прикрепленные метаданные, предварительные изображения, данные цветокоррекции и т. д....
Является ли «размер кадра» таким же, как размеры в пикселях? DPI не имеет значения, так как это просто номер EXIF, который вы можете установить на что угодно, не меняя изображение. Знаете ли вы, что визуально представляют собой артефакты сжатия? Вы проверили субдискретизацию цвета? Мое предположение, разница в сжатии (которая может изменить многие параметры выборки) или разница в размерах пикселей. Вам необходимо опубликовать файлы изображений на сайте обмена файлами (не на сайте обмена фотографиями, поскольку сжатие будет изменено), чтобы получить окончательный ответ.
Мы все можем только строить предположения, пока вы не поделитесь двумя файлами. Насколько нам известно, больший может содержать множество нулей после 0xFFD9, эффективно удваивая размер файла без какого-либо влияния на изображение.
Вычтите изображения и подтяните контраст к результату.
Можно взять JPEG, который использует подвыборку цветности, и преобразовать его в идентичный пикселю JPEG, который этого не делает, хотя для того, чтобы сделать последний пиксель идентичным пикселю, может потребоваться настройка качества, которая сделает файл намного больше.
Когда вы говорите «то же самое», вы имеете в виду то же изображение или просто те же технические параметры?
Пожалуйста, опубликуйте скриншоты, особенно при сравнении масштаба 700%, чтобы более четко проиллюстрировать, что вы имеете в виду.
Вы хотите конкретно определить разницу между этими двумя изображениями или вам просто интересно, как сжатие JPEG дает разные результаты? В первом случае вам необходимо загрузить соответствующие изображения в службу, которая не выполняет повторное сжатие файлов, например Google Drive или OneDrive, и предоставить ссылку. Для последнего см. ответы ниже =)
Некоторые программы могут добавлять большое количество метаданных, например, Photoshop может добавлять большое количество истории редактирования. Вы можете легко обнаружить это, открыв jpg в текстовом редакторе и прокрутив его. Эти метаданные можно удалить, что приведет к созданию двух файлов с идентичными данными изображения, но с очень разными размерами файлов.
Я имею в виду, что они явно не совсем одинаковы.
«такое же количество пикселей, указывающее на то, что сжатие одинаковое» - это не имеет смысла. Любые 2 изображения с одинаковыми размерами XY будут иметь «одинаковую степень пикселизации» при определенном «уровне масштабирования». Но «пикселизация» не имеет ничего общего с «сжатием». (?)
Вся идея сжатия JPEG заключается в том, чтобы отбросить информацию, невидимую человеческому глазу. Поэтому визуальный осмотр не имеет смысла.
@Мистер Уайт А? Под «размерами XY» вы подразумеваете разрешение (например, 1080 x 720)?
@Накопление Да

Ответы (7)

Алгоритм сжатия JPEG работает следующим образом:

  • Вместо сохранения в виде трех плоскостей R, G и B ваше изображение разбивается на 3 плоскости, одна из которых несет яркость, а две — информацию о цвете (также известном как цветность).
  • Следующий шаг называется «подвыборка цветности»: две плоскости цветности затем могут быть уменьшены в два раза в одном измерении (уменьшение цветности вдвое) или в два раза в обоих измерениях (четверование цветности)*.
  • Затем к каждой плоскости применяется сжатие с потерями.

Итак, если вы начинаете с изображения с N пикселями, у вас изначально есть:

N + N + N = 3×N 

пикселей для сохранения. Но с уменьшенной вдвое цветностью у вас есть:

N + ½N + ½N = 2×N 

пикселей, а с четвёртой цветностью:

1 + ¼N + ¼N = 1.5×N 

Итак, когда цветность разделена на четыре части, вы уменьшили размер данных до половины, даже не применяя сжатие. Это напрямую приводит к гораздо меньшему размеру файла.

Некоторые приложения имеют независимые настройки качества и цветности, в то время как другие используют заданную субдискретизацию в зависимости от настройки качества.


* Это работает, потому что наши глаза гораздо более чувствительны к яркости, чем к цвету. Попробуйте это (в Photoshop или Gimp):

  • Сделать снимок
  • Сделайте одну черно-белую копию
  • В другом экземпляре:
    • Уменьшите его на 2 в обоих направлениях (вы даже можете попробовать коэффициент 4)
    • Увеличьте его до исходного размера. По сути, вы размыли свое изображение
  • Импортируйте цветную версию как новый слой
  • Установите его в режим наложения «Цвет» (чтобы полученное изображение было цветом верхнего слоя, примененным к яркости нижнего слоя).

Вы не увидите большой разницы с исходным изображением.

JPEG выполняет квантование с потерями в частотной области, а не в пространственной, поэтому использование одинакового количества битов для кодирования цветности может дать примерно одинаковое качество независимо от того, распределено ли оно по 4-кратному количеству пикселей (субдискретизация 4: 2: 0) или нет. Это не так просто (например, при более низком разрешении цветности важные детали распределяются по меньшему количеству пикселей и, следовательно, имеют более высокую пространственную частоту в блоке DCT), и настройки «качества» могут не смещать квантование в зависимости от того, насколько сильно была субдискретизирована цветность. Но, как и в случае с видео, 4-кратное увеличение пикселей не означает 4-кратное увеличение количества битов, если вы поддерживаете постоянное качество изображения .

Если файлы имеют разный размер, единственный способ, которым данные изображения могут быть идентичными, — это если данные Exif различны (начнем с различия встроенных эскизов).

Предположим, что есть два файла, кодирующих одни и те же данные изображения. У одного нет прикрепленных данных EXIF. Другой имеет полноразмерную копию данных изображения в виде встроенной миниатюры. Разница в размере файла может быть примерно 2:1.

Но видимо изображения разные (наиболее вероятная причина).

Разница между пикселями может быть выполнена с помощью команды ImageMagick compare, как описано в этом ответе StackOverflow .

Он уловит даже незначительные различия.

Я думаю, вопрос в том, что изображения совершенно разные, но имеют одинаковое разрешение и уровень сжатия. Таким образом, одно изображение, которое легче сжать, чем другое, может полностью объяснить это.
@PeterCordes Я стараюсь делать благотворительные оценки интеллекта и принимать вопросы за чистую монету. YMMV.
Они говорят, что у меня есть несколько изображений .jpg, которые ТОЧНО (технические характеристики) одинаковы . Я бы ожидал другой формулировки, если бы они имели в виду, что у них есть куча разных кодировок одного и того же изображения. Вполне разумно ожидать, что разные изображения, снятые одной и той же камерой с одинаковыми настройками, будут иметь одинаковые размеры файлов, если вы не понимаете деталей того, как сжатие с потерями может отбрасывать «информацию» и при этом изображение по-прежнему выглядит примерно так. то же самое для человеческого глаза. Так что я не думаю, что предполагаю, что они тупые, просто пропустил двусмысленность / преувеличил «точно» в названии.
@PeterCordes Я не предполагаю некомпетентного использования «точно».
Ранее я пропустил слово «изображение» в списке вещей, которые были одинаковыми в этих двух файлах, а не только в технических параметрах, таких как разрешение и настройки сжатия. Поэтому я отказываюсь от своего первоначального комментария, я не думаю, что они говорили это в конце концов. (Возможно, ответ, который я написал на основе этого неправильного прочтения, будет полезен будущему читателю >.<)
Если бы одно изображение не могло быть точно представлено на 100% двумя разными потоками данных JPEG, то оптимизаторы JPEG (такие как опция jpegtranкоманды -optimize) были бы невозможны.
@gidds К двум копиям одних и тех же данных изображения могут быть прикреплены разные данные EXIF. Предположим, что у одного нет данных EXIF, а у другого есть полноразмерная миниатюра в EXIF. Соотношение может быть 2:1 с точки зрения размера файла.
@BobMacaroniMcStevens: Да, огромные данные EXIF ​​— очень правдоподобное объяснение соотношения 2:1. Но gidds указал, что ваше утверждение слишком широкое: фактические данные JPEG не обязательно должны быть одинаковыми, чтобы два изображения были одинаковыми. Точно так же, как gzip -1создает файлы большего размера с теми же данными, что и gzip -9, окончательный проход сжатия без потерь в JPEG (после решений о квантовании с потерями) может компенсировать время кодирования процессора по сравнению с размером. Это не может правдоподобно объяснить разницу в размере 2: 1; обычно несколько процентов.
@PeterCordes Также возможно, что ОП ошибся. Возможно файловая система повреждена. Компьютер заражен вредоносным ПО. Или просто космический луч немного перевернулся как раз в определенное время, чтобы создать явление. Из них я бы поставил на человеческую ошибку. Отсюда предложение ImageMagick по операции «compose» и ссылка на StackOverflow.
«Если файлы имеют разный размер, данные изображения могут быть идентичными только в том случае, если данные Exif отличаются» <-- Это неверно. Часть сжатия/кодирования без потерь может быть выполнена более чем одним способом, как и большинство других методов без потерь, таких как ZIP. Типичная ZIP-программа позволит вам сжать больше за счет дополнительного процессорного времени. То же самое возможно с JPEG, но большинство кодировщиков JPEG не позволяют управлять этим аспектом (по крайней мере, независимо от части сжатия с потерями). Вы можете без потерь повторно сжать JPEG, используя файлы jpegtran -optimize.
@Szabolcs Контекст здесь - фотография. Ошибка пользователя на порядки более вероятна. Как и данные Exif. Так же как и повреждение файловой системы.
В контейнере JPEG могут храниться самые разные вещи, кроме основного изображения и данных Exif, например миниатюра JFIF, несжатый XML ( XMP ) и любое количество проприетарных фрагментов данных, специфичных для приложения.

Это два разных изображения, не одной и той же сцены?
Для одного и того же качества восприятия одни изображения сжимаются лучше, чем другие .

У одного есть много гладких или размытых областей (например, небо без большого количества облаков или только объект в фокусе), а у другого много мелких деталей, особенно с острыми краями, такими как трава и кусты, где края каждой травинки и листик видны, или ситцевая ткань?

Крайние значения — равномерный белый или черный (очень маленький) и случайный шум (большой файл).

Ключевым строительным блоком для JPEG является 2D DCT (дискретное косинусное преобразование) (в каждом блоке 8x8 отдельно ), которое преобразует информацию о пространственных пикселях в частотную область . Плавный градиент имеет только низкие частоты, в то время как острые края, такие как текст, травинки и/или листья кустарника, имеют много высокочастотных компонентов. (Версия 1D пытается представить прямоугольную волну как сумму косинусов — на этом сайте есть наглядная демонстрация )

Само это преобразование не вызывает особых потерь. Но он имеет тенденцию давать множество коэффициентов, близких к нулю, и может быть округлен до нуля без большой потери визуального качества. А ненулевые коэффициенты можно округлить ( квантовать ) до менее 8 бит каждый, в зависимости от уровня сжатия. (Насколько сильно вы квантуете и насколько агрессивно вы отбрасываете почти нулевые высокочастотные компоненты, в основном это то, что делает настройка качества сжатия.)

Если бы вы выполнили аналогичное округление для необработанных данных пикселей RGB или YUV, вы бы как бы постеризовали/мультяшно изобразили изображение, сделав области похожего цвета одного цвета. Но если сделать это с частотными коэффициентами DCT, можно отбросить намного больше битов лишь с незначительным визуальным ухудшением. например, звон вокруг острых краев и другие обычные артефакты JPEG.

(Выбор того, как округлять коэффициенты, также является искусством, с некоторым учетом человеческой зрительной системы и того, что мы замечаем/не замечаем.)

После квантования остальная часть JPEG является IIRC без потерь, просто превращая этот разреженный набор ненулевых коэффициентов в битовый поток и выполняя для него сжатие без потерь (аналогично zip).

Забавный факт: это точно такая же математика, на которой основаны MP3/AAC: преобразовать в частотные коэффициенты и округлить их (и полностью отбросить незначащие). Звуковые артефакты MP3 не случайно включают «звон», как и внешний вид JPEG.


Обратите внимание, что пикселизация не является артефактом JPEG . Он имеет тенденцию сглаживать детали, предпочтительно отбрасывая высокочастотные коэффициенты (мелкие детали, включая шум датчика), а не низкочастотные (общие формы в блоке 8x8).

Вы, вероятно, знакомы с тем, как выглядит текст в формате JPEG, когда вы увеличиваете сжатие (отбрасываете/округляете больше информации, чтобы уменьшить размер файла). Сохранение достаточного количества битов, чтобы этого не произошло, — вот почему для высококачественных изображений с большим количеством деталей требуется больше битов, чем для более плавных изображений.

Текст имеет много острых краев и, следовательно, много «энергии» в высокочастотных компонентах DCT. Точное представление требует их сохранения.

То же самое для изображения с шумом, например, из-за зернистости пленки или слабого освещения/высокого значения ISO на цифровой камере. Для JPEG этот шум является сигнальной информацией, которую необходимо попытаться воспроизвести. Это может стоить много бит.


Полу-связанный: почему предустановка «очень быстро» в FFmpeg создает наиболее сжатый файл по сравнению со всеми другими предустановками? - мой ответ касается сжатия видео h.264, но тот же компромисс между качеством и битрейтом применим к неподвижным изображениям. С меньшим значением, придаваемым скорости кодирования/декодирования, потому что это только одно изображение, и поскольку JPEG не имеет возможности сказать «этот блок выглядит как пиксели здесь», поэтому пространство поиска для кодировщика намного меньше.

Более продвинутые форматы неподвижных изображений используют внутреннее предсказание вместо отдельных DCT для каждого блока. например , HEIF представляет собой кадр h.265 I и, как утверждается, требует примерно вдвое меньше места для хранения, чем JPEG с эквивалентным визуальным качеством в среднем. (И может быть даже лучше для изображения с повторяющимся шаблоном, так что многие блоки могут быть закодированы как «скопируйте пиксели оттуда, затем примените это различие», вместо того, чтобы начинать с нуля с шаблоном шахматной доски, который имеет много высокочастотной энергии.)

Я тоже так думал - что изображения/сцены разные - пока не перечитал вопрос: "какие ТОЧНО (dpi, размер кадра, изображение )". Правда, вопрос не на 100% ясен.
@Greenonline: Да, в конце концов я заметил это слово «изображение», обсуждая это в комментариях под ответом Боба. Что меня обмануло, так это то, что «у меня есть несколько изображений .jpg», что не является нормальной ситуацией, когда все они относятся к одному и тому же предмету и имеют разные кодировки. (Или, может быть, большинство копий, одна перекодировка?)

Проблема в том, что мы забываем, что все наши цифровые файлы состоят из двоичных файлов, но наши компьютеры скрывают эти детали. Мы просто видим в нашем проводнике, что какой-то файл what.jpg последний раз обновлялся 1 января 2021 года и имеет размер 14,2 МБ. Затем, если мы откроем файл, мы увидим изображение в нашей программе просмотра изображений после того, как компьютер прочитает инструкции о том, как должен отображаться файл.

Вы можете использовать программное обеспечение, такое как BeyondCompare, для анализа различий между файлами. Ниже приведен скриншот двух изображений, анализируемых с помощью BeyondCompare. Размер изображения слева составляет ~2,1 Мб, а изображения справа — ~1 Мб. Оба они представляют собой файлы в формате .jpg, но тот, что справа, является копией изображения слева, за исключением того, что он был сохранен с более высоким сжатием. Визуально они похожи.

Сравнение изображений с помощью BeyondCompare

Но мы даже не смотрели на то, что видит наш компьютер , чтобы создать образ для нас. Ниже приведен скриншот тех же файлов изображений с использованием шестнадцатеричного сравнения. Шестнадцатеричные значения — это, по сути, «инструкции», которые компьютер читает, чтобы сгенерировать для вас представление изображения.

Анализ изображения с использованием шестнадцатеричного сравнения

Когда я увеличиваю масштаб, скажем, на 700% в одном и том же месте на каждом изображении, я вижу примерно одинаковое количество пикселей, что указывает на то, что сжатие одинаково.

Откройте файл JPEG в графическом редакторе, сохраните изображение с качеством 85. Закройте и снова откройте изображение (1) , снова сохраните его с качеством 100. Теперь сравните 2 выходных изображения. Второе изображение будет иметь больший размер файла, даже если два изображения будут выглядеть почти одинаково.

Таким образом, разные уровни сжатия могут давать (почти) одинаковые изображения.

(1) : чтобы редактор не использовал изображение в памяти.

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

Возможно, было бы полезно, если бы вместо того, чтобы думать о файле изображения как о том, что он «является» изображением или «содержит» изображение, вы думали бы о нем как об инструкциях , которые сообщают вашему компьютеру, как воссоздать изображение.

Предположим, у вас есть картинка, и вы хотите рассказать кому-то еще по телефону, как ее воссоздать. Вы можете разделить свое изображение на «пиксели», а затем сказать другому человеку, сколько пикселей в высоту и сколько пикселей в ширину, и каким именно цветом закрасить каждый пиксель в его копии. Если бы вы это сделали, вы бы отправили им «несжатые» данные изображения.

Однако, в зависимости от изображения, вы можете сэкономить время, если остановитесь, чтобы подумать об этом. Возможно, изображение содержит много белых пикселей. Вы можете начать с того, что скажете: «Покрасьте каждый пиксель в белый цвет», а затем просто сообщите им цвета небелых пикселей. Это было бы формой «сжатия». Возможно, изображение содержит много разных сплошных цветов. Вы можете дать им неполный список пикселей, а затем сказать, что для всех тех, которые я не говорил вам раскрашивать, просто сделайте их такими же, как цвет слева.

Количество различных способов описания изображения практически бесконечно. И найти самые компактные из них - Трудная Проблема . Форматы файлов изображений, такие как .jpg или .png, накладывают некоторые узкие ограничения на количество различных способов описания изображения, но они дают создателю файла некоторую свободу действий в выборе того, сколько времени его компьютер потратит на поиск хорошего изображения. один. Часто есть настройка с таким названием, как «уровень сжатия», «коэффициент качества» и т. д.

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

В целом верно, но для JPEG уровень сжатия в основном зависит от качества и битрейта, а не от процессорного времени и битрейта для того же качества. Трата большего количества процессорного времени на сжатие JPEG в основном связана с окончательным энтропийным кодированием (Huffman IIRC), например gzip -9 по сравнению с gzip -1, и, возможно, выбором решений с потерями для создания битового потока, который хорошо сжимается с учетом предыдущего контекста сжатия.
В отличие от более продвинутых форматов изображений, в которых обнаружение сходства между разными блоками позволит кодировщику сказать декодеру «скопировать отсюда и применить это незначительное различие». ( внутреннее предсказание , которое есть в HEIF, но нет в JPEG.) Это то, на что вы можете потратить много процессорного времени кодирования.
@PeterCordes, конечно, но я просто пытаюсь помочь OP понять, почему разные представления одного и того же изображения могут быть разных размеров. Когда вы добавляете «сжатие с потерями» в микс, это просто означает, что файл содержит «инструкции» для создания «достаточно хорошей» копии вместо идеальной копии. Есть еще много возможных способов сделать это (на самом деле больше способов, чем если бы вы «просто» хотели получить идеальную копию), и размер файла будет зависеть от того, какой способ выберет создатель файла.

Простой способ сравнить два изображения, которые кажутся идентичными, — это использовать режим наложения слоя «Извлечение зерна» в Gimp.

  • Загрузите два изображения в два слоя.
  • Установите режим наложения верхнего слоя на Grain Extract.
  • Слить.

Если изображения идентичны, у вас будет чисто серое изображение. Если есть различия в яркости или цвете, эти различия будут видны. Вы можете использовать кривые, чтобы усилить различия.