Как добиться объединения JPEG без потерь без усечения частичных MCU?

1270
Karan

Я работаю над проектом, для которого мне нужно без потерь объединить тысячи изображений JPEG (здесь я не говорю о форматах Lossless JPEG / JPEG 2000 / JPEG-LS).

Вышеупомянутые изображения имеют различные уровни цветовой подвыборки (1x1, 1x2, 2x1, 2x2), что приводит к различным размерам MCU (8x8, 8x16, 16x8, 16x16 px). Однако в любом данном наборе изображений, которые должны быть объединены, каждое изображение имеет идентичные характеристики.

Пока давайте предположим, что у меня есть только 2 изображения. Размер изображения 1 ( I1 ) составляет 256x256 пикселей, а размер изображения 2 ( I2 ) составляет 239x256 пикселей. Используется субсэмплинг 2x2, так что размер MCU составляет 16x16px. Таким образом, I2, очевидно, имеет частичные MCU на правом краю, поскольку его ширина не делится поровну на 16. (Я читал, что так называемые «частичные» MCU на самом деле содержат данные для полного MCU, но размеры изображения дают команду рендереру отображать только соответствующие пиксели и игнорировать / скрывать лишние.)

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

К сожалению, хотя все остальное работало нормально, кажется, что JpegTran обрезает частичные MCU вместо того, чтобы сохранять их. Таким образом, в приведенном выше примере конечное объединенное изображение содержит все I1, но только 224x256px от I2 . Почему 224? потому что 239 = 14x16 + 15, что означает, что есть 14 полных MCU по ширине и 1 частичный MCU (всего на 1 пиксель меньше, чем полные 16 пикселей). Последние 15px - это то, что становится пустым, приводя к изображению 495x256px с 15px пустых (серых) пикселей на правом краю. Смотрите изображения ниже (позор, который imgur повторно сжимает их):

Image 1(слева) + Image 2(справа)

знак равно Image 1+2

Как вы можете ясно видеть, красная часть (15 пикселей) I2 была обрезана JpegTran. Если бы MCU имели ширину 8 пикселей, потерянная часть была бы самой правой 7 пикселей I2 . Точно так же присоединение I3 (256x239px) * ниже * I1 приведет к потере 7 или 15px, в зависимости от высоты MCU, конечно:

Image 1(вверху) + Image 3(внизу)

знак равно Image 1+3

  • Можно ли даже попытаться сделать то, что я пытаюсь сделать, или так называемое «без потерь» обрезка JPEG «n» допустима только для изображений без частичных микроконтроллеров? (Возможно, именно поэтому эта функция все еще находится в «экспериментальном состоянии» более десяти лет спустя после ее внедрения ...)

  • Пока я точно не знаю , что это невозможно, меня не интересуют предложения о присоединении с потерями. Исключение потери любого поколения - единственная причина, по которой я ломаю голову над этим, иначе я бы сделал это и вычистил бы давным-давно. Также меня не интересуют предложения, связанные с переключением форматов изображений. Я не контролирую источник изображений.

  • Если это можно сделать, то как? Пожалуйста, имейте в виду, что любые предлагаемые альтернативные приложения в идеале должны быть способны к автоматизации, учитывая требования, изложенные выше. (Но учитывая, что маловероятно, что я даже получу полезный ответ с учетом ограничений, я был бы рад любому предложению приложения, если оно действительно работает. Я всегда могу изучить скрипт AutoIT / AHK или что-то позже автоматизировать это.)

  • Я понимаю, что конечное изображение нечетного размера может вызвать проблемы, поэтому я полностью готов принять любое решение, даже если оно приведет к пустым (предпочтительно черным) отступам пикселей вправо / вниз. Я имею в виду, что мне все равно, если I1 + I2 имеет размер 49 6 x256px (отступ 1px) или даже 512x256px (отступ 17px), если конечное изображение содержит все фактические данные изображения из обоих исходных изображений, и весь процесс без потерь. Очевидно, что чем меньше отступ (если есть), тем лучше, но на этом этапе подойдет любое решение.

  • Решение на основе Windows было бы идеальным, но решение на основе Linux было бы вполне приемлемым (предварительно скомпилированные двоичные файлы без внешних зависимостей, если это вообще возможно, вместо просто фрагментов кода). Кроме того, пожалуйста, бесплатное программное обеспечение, если только ничего, кроме платного программного обеспечения не добьется цели.

6
Ух, интересный вопрос и проблема! Я не эксперт, но я бы предположил, что это НЕ было бы возможно, если ОБА изображения содержали частичные микроконтроллеры. Если ваше первое изображение (I1) всегда содержит полные MCU, то это возможно. Вы пробовали IrfanView с плагином JPG_TRANSFORM? В противном случае, если вы готовы к некоторому кодированию, библиотека libjpeg предлагает несколько низкоуровневых способов манипулирования данными JPEG для преобразования без потерь - см. Раздел документации под названием «Действительно необработанные данные: коэффициенты DCT». Mike Fitzpatrick 12 лет назад 0
@Mike: Спасибо за предложения! ** I1 ** всегда содержит полные MCU. Я попробовал IrfanView, но если я что-то упустил, я мог видеть только варианты без потерь вращения и обрезки. Ничего для расширения без потерь или «отрицательного урожая» (так IJG называет это в JpegTran и т. Д.), А также для снижения без потерь. Как вы можете догадаться, мне сначала нужно растянуть исходное изображение без потерь, а затем поместить второе изображение в пустую расширенную область (где происходит усечение). Что касается libjpeg, учитывая, что один и тот же код обрезки 'n' был добавлен ко всем приложениям IJG, как в lib не будет ошибок? Karan 12 лет назад 0
Пожалуйста, дайте мне знать, где находится EXE-файл, который обрабатывает это: так как сейчас мне нужно изменить размер с помощью HexEdit, чтобы обойти эту ошибку: что, очевидно, не очень эффективно. Alex 11 лет назад 0

1 ответ на вопрос

4
Karan

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

... Пожалуйста, поделитесь со мной, где вы получили эту обновленную версию. У меня такая же проблема (это так раздражает, что у меня всего 1 пиксель!), И я не могу найти версию, которая не усекает частичные MCU. Alex 11 лет назад 0
@Alex: Извиняюсь за чрезвычайно задержанный ответ, но я не заходил сюда некоторое время. Надеюсь, это поможет другим, даже если для вас уже слишком поздно. [Страница JpegTran] (http://jpegclub.org/jpegtran/), на которую я ссылаюсь выше, смущенно имеет * две * загрузки для EXE. Один из разделов 1 («* Новая функция масштабирования без потерь в формате jpegtran *») ** НЕ ** тот, который вам нужен здесь. Вместо этого возьмите один из раздела 3 («* DropSlowing Crop 'n' drop (cut & paste) *»). Улучшенный дроп-код был добавлен в приложение его автором 5 октября 2012 года в ответ на предложение моего коллеги, который работал со мной над этим. Karan 10 лет назад 1