jpegtran.exe неправильно вращает изображение

У меня есть только что скомпилированный libjpeg версии 9, и я попытался запустить jpegtran.exe в командной строке с аргументами:

.\jpegtran.exe -rotate 180 -outfile test_output1.jpg testimg.jpg

testimg.jpg: beforetest_output1.jpg: после

Как вы можете видеть, он вращает изображение, но обрезает его, и оно не скомпоновано правильно. Файл использования.txt, поставляемый с пакетом, не совсем актуален, потому что мне пришлось использовать ключ -outfile вместо того, что он говорит:

jpegtran использует синтаксис командной строки, аналогичный cjpeg или djpeg. В Unix-подобных системах вы говорите:

  • jpegtran [переключатели] [входной файл]>выходной файл

В большинстве систем, отличных от Unix, вы говорите:

  • jpegtran [переключает] входной файл выходной файл

где и входной, и выходной файлы являются файлами JPEG.

Чтобы указать закодированное представление JPEG, используемое в выходном файле, jpegtran принимает подмножество переключателей, распознаваемых cjpeg:

  • -optimize Выполнить оптимизацию параметров энтропийного кодирования.
  • -progressive Создать прогрессивный файл JPEG.
  • -arithmetic Использовать арифметическое кодирование.
  • -restart N Выдавать маркер перезапуска JPEG через каждые N строк MCU или через каждые N блоков MCU, если к числу добавлено «B».
  • -scans файл Использовать сценарий сканирования, указанный в указанном текстовом файле.

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

Изображение можно преобразовать без потерь, указав один из этих переключателей:

  • -flip horizontal Отразить изображение по горизонтали (влево-вправо).
  • -flip vertical Отразить изображение по вертикали (сверху-вниз).
  • -rotate 90 Повернуть изображение на 90 градусов по часовой стрелке.
  • -rotate 180 Повернуть изображение на 180 градусов.
  • -rotate 270 Повернуть изображение на 270 градусов по часовой стрелке (или на 90 против часовой стрелки).
  • -transpose Транспонировать изображение (по оси UL-к-LR).
  • -transverse Поперечное транспонирование (через ось UR-LL).

Как ни странно (а может и нет), если я выполню .\jpegtran.exe -rotate 180 -outfile test_output2.jpg test_output1.jpg, я верну исходное изображение без каких-либо проблем с отсечением. Он переворачивает обрезанные части, но просто не выравнивает их с остальной частью изображения.

test_output2.jpg: после еще одного поворота на 180

Я получаю тот же результат, дважды выполняя jpegtran.exe -rotate 90.

Кроме того, я попробовал это с большим файлом .jpg, что привело к той же проблеме, но размер файла был на 18 КБ меньше для вывода. Я предполагаю, что проблема связана с этим.


Изменить. Я также нашел эту рекламу, которая, кажется, описывает проблему:

Поведение jpegtran по умолчанию при преобразовании изображения нечетного размера предназначено для сохранения точной обратимости и математической согласованности набора преобразований. Как уже говорилось, транспонирование может перевернуть всю область изображения. Горизонтальное зеркальное отображение оставляет любой частичный столбец iMCU на правом краю нетронутым, но может перевернуть все строки изображения. Точно так же вертикальное зеркальное отображение оставляет нетронутой любую частичную строку iMCU на нижнем краю, но может перевернуть все столбцы. Другие преобразования могут быть построены как последовательности операций транспонирования и переворачивания; для согласованности их действия с краевыми пикселями определяются как конечные результаты соответствующей последовательности транспонирования и отражения.

Переключатель -trim работает, если его можно так назвать, и обрезает неорганизованные данные, но изображение становится меньше и данные теряются.

test_output5.jpg: обрезанный вывод

Добавление переключателя -perfect, который якобы останавливает вышеперечисленное, приводит к следующему: transformation is not perfect для вывода и без изображения.

Так нельзя ли без потерь повернуть .jpg? Я мог бы сам перейти к рисованию и реконструировать исходное изображение, просто переместив линии краев в нужное место. Есть ли способ сделать это в libjpeg?


person Enigma    schedule 30.01.2013    source источник


Ответы (1)


Вращение без потерь работает с целыми блоками DCT, содержащимися в файле JPEG. Эти блоки всегда имеют размер 8x8 или 16x16 пикселей (в зависимости от настроек сжатия понижающей выборки). Файл содержит ширину и высоту, поэтому лишние пиксели могут быть отброшены при декодировании изображения, но нет возможности переместить отсечение с правого/нижнего края на левый/верхний край. Программное обеспечение делает все возможное с неразрешимой проблемой.

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

person Mark Ransom    schedule 30.01.2013
comment
Итак, в нем говорится, что он предназначен для поддержания математической обратимости. Есть ли способ как-то игнорировать эту директиву? Даже с потерями? Я попробую /16 с некоторыми изображениями. Я предполагаю, что IP-камера, которую я использую, будет иметь правильное разрешение /16. - person Enigma; 31.01.2013
comment
@Enigma, я недостаточно знаком с jpegtran, чтобы знать, есть ли другой способ поворота, кроме без потерь. Даже если это возможно, теперь вам нужно выбрать настройку качества, что не является проблемой для операций без потерь. - person Mark Ransom; 31.01.2013
comment
Я нахожу забавным, что поставляемые тесты, поставляемые с libjpeg, не делятся на 16, но я попробовал изображение /16 WxH, и оно отлично работает, так что спасибо. - person Enigma; 31.01.2013