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

Имам прясно компилиран libjpeg версия 9 и се опитах да стартирам jpegtran.exe в командния ред с аргументите:

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

testimg.jpg: beforetest_output1.jpg: след

Както можете да видите, той наистина завърта изображението, но го изрязва и не е събрано правилно. Файлът usage.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 vertical Огледално изображение вертикално (горе-долу).
  • -rotate 90 Завъртете изображението на 90 градуса по часовниковата стрелка.
  • -rotate 180 Завъртане на изображението на 180 градуса.
  • -rotate 270 Завъртете изображението на 270 градуса по часовниковата стрелка (или 90 ccw).
  • -транспониране Транспониране на изображение (през UL към LR ос).
  • -напречно Напречно транспониране (през UR към LL ос).

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

test_output2.jpg: след друго завъртане на 180

Получавам същия резултат, като изпълня jpegtran.exe -rotate 90 два пъти.

Освен това го изпробвах на по-голям .jpg файл, което доведе до същия проблем, но размерът на файла беше с 18 KB по-малък за изхода. Предполагам, че проблемът е свързан с това.


Редактиране - Намерих и това аннотиране, което изглежда описва проблема:

Поведението по подразбиране на 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
Намирам за забавно, че доставените testimg, които идват с libjpeg, не се делят на 16, но опитах /16 WxH изображение и то работи перфектно, така че благодаря. - person Enigma; 31.01.2013