Как добавить рамку к фотографии в формате JPEG без ущерба для качества?

У меня есть фото в формате JPEG с разрешением 4680x3120. Я хочу добавить белую рамку вокруг этой фотографии, превратив ее в фотографию 5200x3467 (для печати).

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

Есть ли способ (какая-то более профессиональная программа) добавить что-то к фотографии в формате JPEG, например, рамку, не затрагивая исходную часть фотографии, не снижая ее качества?

Ответы (7)

Хотя ответ Филиппа - лучший способ, можно делать то, что вы хотите, полностью в сфере JPEG.

JPEG работает, разбивая ваше изображение на блоки, называемые минимальными единицами кодирования (MCU), обычно 16 × 16 каждый, и сжимая их по отдельности. Вы можете увидеть это на изображениях, когда очень сильно увеличиваете уровень сжатия. При более разумных уровнях сжатия блоки смешиваются так плавно, что вы никогда не видите границ.

Мы можем воспользоваться этим фактом, чтобы без потерь добавить к изображению простую белую рамку. Нам просто нужно создать пустой массив белых блоков, равный размеру выходного изображения, а затем поместить исходные блоки MCU JPEG в середину.¹

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

Я не знаю ни одной программы, которая делает только это. Самое близкое, что я знаю, это что-то, что выполняет обратную операцию: у jpegtran есть функция кадрирования, которая без потерь обрезает части краев изображения. середина нетронутая.

Самое простое готовое решение, которое я знаю, это плагин Better JPEG Lossless Resave для Photoshop. Он использует методы, основанные на идеях, приведенных выше, для копирования MCU из исходного изображения везде, где это возможно, чтобы избежать их повторного создания из несжатой версии, как это обычно делает Photoshop.³


Отступления:

  1. Вы можете подумать, что результирующая рамка будет не совсем белой , так как потери JPEG создадут некоторую разницу в цвете на выходе. Я провел некоторое тестирование, и, по крайней мере, в Photoshop, чисто белое изображение, сохраненное с помощью Save For Web JPEG level 10 (т.е. «низкое» качество), приводит к декодированному изображению, которое по-прежнему остается чисто белым.

    Я определил это двумя тестами:

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

    Во-вторых, когда я не увидел ожидаемых различий, я удалил корректирующий слой и вернул слой JPEG в режим наложения «Нормальный», взял инструмент «Пипетка» и просмотрел все изображение в поисках пикселя, который не отображался как RGB (255 255 255). ) на информационной панели. Я так и не нашел. Я ожидал увидеть, как цифры немного мерцают, когда я протирал изображение, но они оставались стабильными.

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

    Интересно, что с чисто черными блоками этого не происходит. По крайней мере, с реализацией Photoshop при декодировании они превращаются в RGB (1,1,1), а не в RGB (0,0,0).

    Суть в том, что вам не нужно беспокоиться о напыленных точках в этой граничной области при печати изображения, полученного с использованием описанной выше техники.

  2. jpegtran— это программа командной строки, но есть также программа для Windows с графическим интерфейсом, основанная на том же коде, который называется jpegcrop.

  3. Увы, этот плагин только для Windows.

Я использовал программу под названием JPEG Wizard, которая обеспечивала такую ​​функциональность. У него также была очень хорошая возможность применять разные коэффициенты сжатия к разным частям JPEG. Таким образом, можно использовать высокое качество для головы и рук человека, среднее качество для его одежды и более низкое качество для фона, и, таким образом, в итоге получится файл меньшего размера, но лучшее общее качество, чем если бы вы использовали среднее качество для всего.
У меня не было возможности попробовать это, но этот пост в блоге предполагает, что jpegtranфункция урожая также может быть использована для расширения. (Однако не уверен, какого цвета будут расширенные границы.)
@mattdm: Да, jpegtranтакже можно расширить изображение, но оно всегда дополняется жестко закодированным средним серым, RGB (128 128 128). Он делает это просто потому, что это единственный простой вариант, поскольку в пространстве коэффициентов DCT вы можете сделать это с помощью простого bzero()вызова. Я попытался изменить это диким хаком , который не работает, но должен дать вам ощущение уродства. разводит руками в отчаянии
@WarrenYoung: чтобы изменить цвет блоков заполнения, вам, вероятно, потребуется изменить только первый (DC) коэффициент, а остальные оставить равными нулю. Конечно, коэффициенты сжаты, так что... в любом случае, это должно быть выполнимо, но я согласен, что это не так тривиально, как может показаться.
@IlmariKaronen: Звучит правдоподобно. Еще одна проблема с моим патчем заключается в том, что он вызывает ошибку программы; Я предполагаю, что неправильно истолковываю размер этих JBLOCK2D-массивов, поэтому я записываю в пространство памяти, которым не владею. Не стесняйтесь делать свой собственный патч или риффовать на мой. Я думаю, что преследовал этого кролика так далеко, как хотел.
Что касается вашего последнего замечания — наибольшая экономия достигается за счет отказа от высокочастотной информации. Выигрыш от отказа от точности цвета сплошного блока пикселей не может превышать байта или двух, так что это никогда или почти никогда не делается. Если есть какая-либо потеря информации, это связано с преобразованием цветового пространства YUV<->RGB.
(Как) Это работает, если толщина границы не кратна 16 пикселям? Я предполагаю, что вы нарушите формат, если сделаете это вручную на двоичном уровне.
@Raphael: Я думаю, что если бы я написал программу, которая делает это в качестве основной цели, я бы округлил размеры верхней и левой границы до ближайшего кратного 16, независимо от ввода пользователя. При разрешении 240 dpi для печати это создает максимальную ошибку смещения на странице 1,6 мм. Вероятно, вы можете получить такую ​​большую ошибку из-за проскальзывания бумаги, когда она входит в подающие ролики. Затем справа и снизу вы получите до 15 пикселей изображения или границы, требующей повторного кодирования, прежде чем вы сможете вернуться к «чистым» белым блокам пикселей, чтобы закончить эту границу.

Здесь следует помнить, что вы теряете качество при сохранении фотографии в формате сжатия с потерями. Пока вы сохраняете фотографию в формате без потерь (PSD, TIFF и т. д.) после добавления границы, вы не потеряете больше данных, чем вы уже потеряли, сохранив фотографию в формате JPEG.

Спасибо. И это верно даже при использовании «дерьмовой» программы, такой как Paint, при сохранении, например, в TIFF?
По крайней мере, согласно моему быстрому тесту, Paint использует алгоритм сжатия LZW без потерь при сохранении TIFF, поэтому все выглядит нормально.
Имейте в виду, что это, вероятно, значительно увеличит размер изображения...
Paint также поддерживает PNG, который также является форматом без потерь.
+1 за это, поскольку ответы, в которых обсуждается сохранение обратно в jpeg, несовместимы со всеми параметрами кодирования jpeg.

Это не совсем без потерь, но вы можете приблизиться к этому, используя GIMP (или какой-либо другой редактор с аналогичной функцией) и следующие два приема:

  1. Во-первых, убедитесь, что ширина границы, которую вы добавляете, кратна 8 пикселям (и предпочтительно кратна 16 пикселям).

    Это важно, поскольку алгоритм сжатия JPEG разбивает изображение на блоки размером 8×8 пикселей *, начиная с верхнего левого угла, и независимо применяет алгоритм сжатия с потерями к каждому блоку. Таким образом, по крайней мере в принципе, вы можете без потерь дополнить изображение JPEG, добавляя полные блоки размером 8×8 пикселей вокруг существующих. Однако если вы попытаетесь добавить рамку шириной не в целое число блоков, блоки в дополненном изображении не совпадут с блоками в оригинале, и некоторые потери при сжатии будут неизбежны.

    *) На самом деле, в большинстве изображений JPEG используется подвыборка цветности , что означает, что только часть изображения в градациях серого фактически сжимается в блоки 8×8, тогда как каналы цветности перед сжатием уменьшаются на 50%, что делает их эффективный размер блока 16× 16 пикселей. Таким образом, для достижения наилучших результатов ширина границы должна быть кратна 16 пикселям. Тем не менее, вы обычно можете обойтись рамкой в ​​8 (или 24, или 40 и т. д.) пикселей, так как небольшая потеря сжатия в цветности не очень заметна.

  2. Вторая часть хитрости заключается в том, чтобы при сохранении конечного изображения установить флажок «Использовать настройки качества из исходного изображения» в диалоговом окне «Экспорт изображения в формате JPEG» (в разделе «Дополнительные настройки»). Сделайте это, даже если кажется, что это приведет к более низкому качеству, чем вы обычно используете!

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


В качестве быстрой демонстрации я взял это тестовое изображение JPEG из Wikimedia Commons , изначально сохраненное с довольно низкой настройкой качества 50, и добавил к нему причудливую (что-то вроде) черно-белую рамку 8px, используя метод, описанный выше:

Тестовое изображение с рамкой 8 пикселей, в основном без потерь

Вот разница между исходным (15,1 КБ) и отредактированным изображением (16,7 КБ), показанным с использованием режима слоя GIMP «Извлечение зерна»:

Разница между дополненным изображением и оригиналом

Вы можете увидеть очень небольшие ошибки цветности, вызванные тем, что ширина границы не кратна 16, и (если присмотреться) несколько блоков, где также были небольшие потери в канале яркости из-за округления. Тем не менее, визуально исходное изображение и дополненное изображение почти неразличимы, даже при двукратном увеличении и поочередном переключении между ними.

В частности, сравните это с результатом повышения качества JPEG с 50 до 60 перед сохранением дополненного изображения, что дает следующее изображение размером 17,6 КБ:

Тестовое изображение с рамкой 8 пикселей, качество увеличено с 50 до 60.

При большом увеличении точно видно, что отредактированное изображение в некоторых местах заметно размытее оригинала, и снятие разницы с экстрактом зерна подтверждает это:

Разница между дополненным изображением (при q60) и оригиналом

«установка этого флажка, похоже, не влияет на настройку «Прогрессивный». Это не ошибка, поскольку прогрессивное кодирование — это параметр кодирования, а не параметр качества. Jpegtran может конвертировать изображения в прогрессивный формат и обратно без потерь.
@tepples: ты прав; Я удалил этот абзац. По какой-то причине у меня сложилось впечатление, что переключение прогрессивного режима приведет к тому, что настройки качества не будут совпадать, но быстрый тест, кажется, подтверждает, что я ошибался.
Этот ответ неправильно понимает, что делает настройка «Использовать настройки качества из исходного изображения». Это не попытка наилучшим образом сохранить перекодированное изображение, а применить к изображению примерно такое же ухудшение (те же квантователи), что и в прошлый раз. После повторного сохранения качество изображения будет примерно в два раза хуже, чем у оригинала, поскольку оно было ухудшено во второй раз на ту же величину, что и при первом сохранении. Этот параметр бесполезен для сохранения качества; только если вы хотите сэкономить байты, повторно сжимая изображение, которое уже сильно ухудшилось, и вы не возражаете.
@thomasrutter: я не могу поставить минус комментарию, поэтому я просто укажу вам на исходное сообщение на форуме, описывающее эту функцию , и, в частности, на эту цитату: « Если вы внесли только несколько изменений в изображение, то повторно использование одних и тех же таблиц квантования даст вам почти то же качество и размер файла, что и исходное изображение. Это сведет к минимуму потери, вызванные шагом квантования, по сравнению с тем, что произошло бы, если бы вы использовали разные таблицы квантования » .
@thomasrutter: Кроме того, если вы не верите этому сообщению, почему бы просто не проверить его самостоятельно (или посмотреть на тестовые изображения, которые я включил в свой ответ)? Достаточно легко убедиться, что открытие JPEG-изображения в GIMP и его повторное сохранение с параметром «Использовать настройки качества из исходного изображения» вызывает лишь минимальную (хотя, увы, не всегда нулевую) деградацию, тогда как изменение настройки качества (даже незначительное вверх!) обычно приводит к значительно более высоким потерям квантования.
Это описание неверно; единственный способ минимизировать потери при квантовании — уменьшить квантование; повторное сохранение с очень высоким качеством (низкое квантование) будет намного эффективнее при приближении к тому же качеству, что и у источника, чем повторное сохранение с теми же квантователями, что и в прошлый раз. В Интернете много дезинформации об этой функции, и люди думают, что это волшебный способ улучшить качество.
«изменение настройки качества (даже в большую сторону!) обычно приводит к значительным потерям при квантовании». Этого не произойдет, это не то, как работает квантование, к сожалению, многие источники подразумевают или прямо заявляют, что это так. Проведите тестирование с PSNR или SSIM или какой-либо другой общей метрикой, показывающей, что это так (повышение качества приводит к худшему качеству, чем при равных квантователях), и я буду исправлен, но в основном это не так.
@thomasrutter: Хорошо, хорошо. Загрузите это изображение в формате JPEG , откройте его в GIMP и сохраните дважды: один раз с параметром «Использовать настройки качества из исходного изображения» и один раз с повышением качества до 40. Сравните каждый файл JPEG с несжатым базовым изображением . Используя ImageMagickcompare , я получаю PSNR 34,5826 для оригинального JPEG, 34,5752 для копии, повторно сохраненной с теми же настройками качества, и 34,3653 для копии, повторно сохраненной в q40. Достаточно хорошо?
Что ж, это интересно. Это локальный максимум? Как далеко подняться по шкале качества, пока PSNR не станет выше результата того же Q? Это выше в Q 41? Вопрос 39? Или нужно больше, например, Q 50?
@thomasrutter: я не знаю; это только первое тестовое изображение и первые настройки, которые я попробовал. Я дал ссылку на все инструменты и исходные изображения, которые использовал, чтобы вы могли сами воспроизвести результаты; мне потребовалось менее 15 минут, чтобы выполнить этот быстрый тест, включая поиск в Google «PSNR», чтение статьи в Википедии и поиск страницы справки ImageMagick, так что вы сможете воспроизвести его максимум за пять. Вы тот, у кого есть странные (и явно контрфактические) идеи о том, как здесь работает сжатие JPEG, поэтому я бы сказал, что вы должны проверить их, а не просто ожидать, что данные вам будут кормить с ложки.
Пс. Я довольно часто бываю в чате , если вы предпочитаете продолжить обсуждение там.
Просто для сравнения, вот еще один пример в ответе на другой вопрос. Мое понимание в теории согласуется с Илмари, но, по крайней мере, в моем примере практика кажется гораздо более похожей на то, что говорит Томас — по крайней мере, когда начинается с сильно деградированного изображения. (Я думаю, что надгробие — плохой пример для этой цели, потому что потеря деталей на камне менее заметна, чем на человеческой коже.)
@mattdm: похоже, это очень зависит от программного обеспечения; Я попытался воспроизвести ваши результаты из этого ответа в GIMP, и кажется, что GIMP (по крайней мере, v2.8.10) немного лучше сохраняет качество JPEG, чем ImageMagick (какую бы версию вы ни тестировали). Ваше первое изображение, сохраненное один раз в q75, имеет PSNR 34,0298, в то время как изображение, сохраненное дважды в q75, имеет PSNR всего 32,8169 (а повторно сохраненное 8 раз имеет PSNR 32,6459). Для сравнения, однократное сохранение того же исходного изображения в GIMP на q75 дает PSNR 36,4560; открытие и повторное сохранение с тем же качеством снижает его лишь незначительно, до 36,3295.
@IlmariKaronen Круто - это приятно знать, потому что в большинстве случаев, когда мне не все равно, я использую Gimp.
@mattdm: Пс. Кажется, есть разница между повторным сохранением JPEG напрямую с помощью «Использовать настройки качества из исходного изображения» и копированием и вставкой его в новое окно изображения и сохранением оттуда (опять же в q75); последний дает PSNR 36,2973, что немного хуже, чем непосредственное повторное сохранение (но все же намного лучше, чем вы получили с ImageMagick). Я предполагаю, что это связано с тем, что шаг копирования-вставки заставляет GIMP забыть о любых настройках сжатия, которые он сохранил как внутренние метаданные при открытии JPEG.
Может ли это конкретное несоответствие быть связано с используемым режимом субдискретизации цветности? «Использовать настройки качества из исходного изображения» также устанавливает субдискретизацию цветности в соответствии с оригиналом, а не только Q. Хотя вы, возможно, уже делаете это.
@thomasrutter: я использовал субдискретизацию 4: 2: 0 для всех своих тестов, поскольку IME является наиболее распространенной настройкой в ​​общем использовании (и поскольку для исходной пограничной задачи это наихудшая ситуация). Это также то, что использовалось в тестовых изображениях, которые я скачал из Википедии, так что здесь нет никакой разницы. Я не могу со 100% уверенностью сказать, что использовал mattdm, так как он конвертировал все свои изображения в PNG, но это тоже похоже на 4:2:0.

Извините, если это не совсем то, что вы хотели, но...

Похоже, вы добавляете белую рамку в качестве помощи для позиционирования изображения при печати. Почему бы не сосредоточиться на правильном изучении интерфейсов печати и избежать таких хитрых хаков? Другая проблема, которая возникает, заключается в том, разрешаете ли вы программе печати изменять размер изображения 4680x3120, чтобы он соответствовал правильному DPI/разрешению. Это может иметь более серьезные последствия, чем повторное сохранение в формате jpeg.

Оба действительные точки, спасибо. Однако я загрузил свою фотографию в одну из этих интернет-магазинов, поэтому у меня нет контроля над реальным принтером.

Предыдущие ответы очень хорошие.

Я просто добавлю некоторые «психологические аспекты» формата jpg.

Если jpg хорошо подготовлен, он теряет только около 0,5% информации. Это в подавляющем большинстве случаев то, что человеческий глаз не может увидеть. Вам нужна программа, чтобы провести некоторый анализ и увидеть различия (например, анализ, который только что сделал Илмари).

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

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

Если вас действительно беспокоит качество, вы, вероятно, не будете использовать Paint. Формат JPG имеет некоторые настройки, которыми вы вообще не можете управлять в Paint.

Вот мой список бесплатных программ, где вы действительно можете контролировать сжатие jpg, и вариант, который вам нужно выбрать. (Все они в диалоговом окне сохранения jpg)

Irfanview - Включите Отключить субдискретизацию цвета цветности.

FastStone Image Viewer - субдискретизация цвета: нет.

GIMP — субдискретизация 4:4:4

Вывод. Не используйте Пейнт.

Одно я еще не проверял. Если все эти программы поддерживают встроенный цветовой профиль. Я отредактирую свой пост позже.

Кто-то проголосовал -1 за этот ответ. Обычно мне все равно, потому что я знаю, что могу сказать что-нибудь глупое. В данном конкретном случае, какая часть ответа неверна?
Я не голосовал (за или против), но вы, возможно, захотите поработать над своим правописанием и грамматикой, чтобы произвести лучшее первое впечатление (а также, честно говоря, чтобы ваш ответ было легче читать). Также на этот вопрос уже есть несколько ответов (и мой, тем более, получился достаточно длинным); в какой-то момент некоторые люди могут начать голосовать против (или, по крайней мере, не голосовать за) ответы, которые явно не добавляют что-то новое к существующим. Кроме того, постарайтесь структурировать свой ответ так, чтобы важные части выделялись с первого взгляда; в этом случае единственная часть, которую вы выделили жирным шрифтом , — это неважная сноска.
Спасибо за комментарий, Ильмари. Я изо всех сил пытаюсь думать на английском, так как это не мой родной язык. Я буду искать орфографический инструмент. Я не уверен, есть ли грамматика. - Что касается второй части комментария, я понимаю, что логика StackExchange заключается в том, чтобы ответить на вопрос независимо, потому что поток ответов не фиксирован, потому что они могут менять порядок или редактироваться. Я посмотрю на это. (Я удалил жирный текст) Еще раз спасибо. :о)
«он теряет только около 0,5% информации» [нужна цитата] :)
Эй, Уоррен, вот он: otake.com.mx/Apuntes/PruebasDeCompresion2/… Он на испанском языке, пожалуйста, используйте сейчас Google Translate, и мне нужно его обновить. На самом деле это меньше 0,392% :)

IrfanView хорошо работает для наборов изображений. Вот несколько заметок

Вот моя хранимая процедура для вставки границы - Процедура Infran для добавления границы

  1. Щелкните изображение правой кнопкой мыши, «Открыть с помощью» -> «InfranView».
  2. Нажмите «б»
  3. Установите флажок «Использовать дополнительные параметры» в левом верхнем углу, нажмите «Дополнительно».
  4. Проверьте «Размер холста», нажмите «Настройки».
  5. Введите ширину каждой границы (левая сторона, правая сторона, верхняя сторона, нижняя сторона)
  6. Нажмите «ОК»
  7. Выберите «Перезаписать существующие файлы».
  8. Нажмите «ОК»
  9. Введите выходной каталог «Выходной каталог для файлов результатов:»
  10. Перейдите к изображению, чтобы добавить границу, и дважды щелкните его в верхнем списке. Это добавляет его в список «входные файлы:» в нижнем списке.
  11. Нажмите «Начать партию».
Не могли бы вы объяснить, что особенного в этом методе, чтобы он соответствовал требованиям плаката и не снижал качество изображения? При первом чтении может показаться, что JPEG отправляется через весь цикл распаковки-повторного сжатия, которого автор пытается избежать.
хм, вы привнесли интересный момент в отношении жизненного цикла изображения в процессе, который я здесь перечисляю, я не думал об этом. Возможно, вы правы, если вы хотите, чтобы я удалил или изменил свое сообщение, пожалуйста, дайте мне знать :)!

Вы можете сделать это бесплатно с помощью Adobe Acrobat! Щелкните правой кнопкой мыши свою фотографию, затем выберите «Открыть с помощью Adobe Acrobat». В Adobe нажмите «Редактировать PDF». Выберите все изображение (Ctrl A), затем уменьшите его, чтобы вокруг него была белая рамка. Затем нажмите «Экспортировать как» и выберите нужный формат (JPEG, PNG и т. д.).

Не могли бы вы объяснить, как это позволяет избежать потери качества из-за цикла декомпрессии/рекомпрессии JPEG?