Wie erreiche ich eine verlustfreie JPEG-Verbindung, ohne partielle MCUs abzuschneiden?

1268
Karan

Ich arbeite an einem Projekt, für das ich Tausende von JPEG-Bildern verlustfrei zusammenfügen möchte (ich spreche hier nicht von den Verlustfreien JPEG / JPEG 2000 / JPEG-LS-Formaten).

Vorgenannte Bilder haben unterschiedliche Stufen der Chroma-Unterabtastung (1x1, 1x2, 2x1, 2x2), was zu unterschiedlichen MCU-Größen (8x8, 8x16, 16x8, 16x16 px) führt. In jedem gegebenen Satz von Bildern, die zusammengefügt werden sollen, hat jedes Bild identische Eigenschaften.

Nehmen wir an, ich habe nur 2 Bilder. Bild # 1 ( I1 ) ist 256x256px groß und # 2 ( I2 ) ist 239x256px groß. 2x2-Subsampling wird verwendet, so dass die MCU-Größe 16x16px beträgt. Offensichtlich hat I2 daher partielle MCUs am rechten Rand, da seine Breite nicht gleichmäßig durch 16 teilbar ist. (Ich habe gelesen, dass sogenannte "partielle" MCUs tatsächlich die Daten für eine vollständige MCU enthalten, aber die Bildabmessungen weisen den Renderer an um nur die relevanten Pixel anzuzeigen und die zusätzlichen zu ignorieren / ausblenden.)

Als ich mich nach Tools umsah, die mir dabei helfen konnten, stieß ich auf eine modifizierte Version von JpegTran, die eine verlustfreie Funktion zum Ausschneiden und Ausschneiden (Cut & Paste) enthält. Bei allen anderen Apps, die verlustfreie JPEG-Bearbeitung unterstützen, wird anscheinend der Code von IJG (JpegTran) verwendet, sodass dies die logische Wahl war. Angesichts der schiere Anzahl von Bildern wollte ich auch etwas, das vorzugsweise von der Befehlszeile aus ausgeführt werden kann, damit ich den Prozess mit einem Skript automatisieren kann.

Während alles andere gut funktionierte, scheint es, als würde JpegTran die partiellen MCUs abschneiden, anstatt sie beizubehalten. Im obigen Beispiel enthält das endgültige verbundene Bild also nur I1, aber nur 224 x 256 Pixel von I2 . Warum 224? Weil 239 = 14x16 + 15, was bedeutet, dass es 14 volle MCUs entlang der Breite gibt, und 1 partielle MCU (nur 1px kurz vor dem vollständigen 16px). Bei den letzten 15 Pixeln wird das Bild ausgeblendet, was zu einem Bild mit 495 x 256 Pixeln und 15 Pixeln leerer (grauer) Pixel am rechten Rand führt. Siehe Bilder unten (schade, dass imgur sie erneut komprimiert):

Image 1(links) + Image 2(rechts)

= Image 1+2

Wie Sie deutlich erkennen können, wurde der rote Anteil (15px) von I2 von JpegTran abgeschnitten. Wenn die MCUs eine Breite von 8 Pixeln hätten, wäre der verlorene Teil der am weitesten rechts liegende 7 Pixel von I2 gewesen . In ähnlicher Weise würde ein Beitreten von I3 (256x239px) * unter * I1 je nach Höhe der MCU natürlich den Verlust von 7 oder 15px verursachen:

Image 1(oben) + Image 3(unten)

= Image 1+3

  • Kann das, was ich versuche, sogar ausgeführt werden, oder ist der sogenannte "verlustfreie" JPEG-Ausschnitt nur für Bilder ohne partielle MCUs gültig? (Vielleicht befindet sich das Feature deshalb mehr als ein Jahrzehnt nach seiner Einführung noch in einem "experimentellen Zustand" ...)

  • Bis ich sicher bin, dass es unmöglich ist, interessiere ich mich nicht für Vorschläge für einen verlustbehafteten Beitritt. Jeden Generationsverlust zu vermeiden, ist der einzige Grund, warum ich mir dabei den Kopf zerbreche, sonst hätte ich das schon vor Jahren gemacht und abgestaubt. Ich interessiere mich auch nicht für Vorschläge zum Wechseln von Bildformaten. Ich kontrolliere nicht die Quelle der Bilder.

  • Wenn es möglich ist, wie? Bitte beachten Sie, dass die vorgeschlagenen alternativen Apps aufgrund der oben genannten Anforderungen idealerweise automatisierbar sein müssen. (Aber angesichts der Tatsache, dass es unwahrscheinlich ist, dass ich angesichts der Einschränkungen auch eine nützliche Antwort bekomme, wäre ich mit jedem App-Vorschlag zufrieden, solange es tatsächlich funktioniert. Ich kann immer in ein AutoIT / AHK-Skript schauen oder später etwas dazu automatisiere es.)

  • Ich verstehe, dass ein endgültiges Bild mit ungerader Größe Probleme verursachen kann. Daher bin ich bereit, jede Lösung zu akzeptieren, selbst wenn es zu leeren (vorzugsweise schwarzen) Auffüllpixeln nach rechts / unten führt. Was ich meine ist, ist mir egal, ob I1 + I2 49 6 x256px (1px-Auffüllung) oder sogar 512x256px (17px-Auffüllung) groß ist, solange das endgültige Bild alle tatsächlichen Bilddaten von beiden Quellbildern enthält, und Der gesamte Prozess ist verlustfrei. Je geringer die Polsterung (falls vorhanden), desto besser, aber an diesem Punkt ist jede Lösung geeignet.

  • Eine Windows-basierte Lösung wäre perfekt, aber eine Linux-basierte Lösung wäre durchaus akzeptabel (vorkompilierte Binärdateien ohne externe Abhängigkeiten, wenn überhaupt möglich, anstatt nur Code-Snippets). Freeware bitte auch, es sei denn, es wird ausschließlich kostenpflichtige Software verwendet.

6
Wow, interessante Frage und Problem! Ich bin kein Experte, aber ich würde vorschlagen, dass es NICHT möglich wäre, wenn BEIDE Bilder partielle MCUs enthalten. Wenn Ihr erstes Image (I1) immer vollständige MCUs enthält, ist dies möglicherweise möglich. Haben Sie IrfanView mit dem Plug-In JPG_TRANSFORM ausprobiert? Ansonsten bietet die Bibliothek `libjpeg` einige Möglichkeiten zur Bearbeitung von JPEG-Daten für verlustfreie Transformationen - siehe den Abschnitt 'Wirklich Rohdaten: DCT-Koeffizienten'. Mike Fitzpatrick vor 11 Jahren 0
@ Mike: Danke für die Vorschläge! ** I1 ** enthält immer volle MCUs. Ich habe IrfanView ausprobiert, aber wenn mir etwas fehlt, konnte ich nur Optionen für verlustfreies Drehen und Zuschneiden sehen. Nichts für verlustfreie Erweiterung oder "negative Ernte" (so spricht IJG in JpegTran usw.) oder für verlustfreies Ablegen. Wie Sie sich vorstellen können, muss ich zunächst das ursprüngliche Bild verlustfrei erweitern und dann das zweite Bild auf den leeren erweiterten Bereich (dort, wo die Kürzung erfolgt) ablegen. Was libjpeg angeht, in Anbetracht der Tatsache, dass für alle Apps von IJG derselbe Crop 'n' Drop-Code festgelegt wurde, wie wäre die lib fehlerfrei? Karan vor 11 Jahren 0
Bitte lassen Sie mich wissen, wo sich eine EXE-Datei befinden kann, die sich damit befasst: Da ich vorerst die Größe über HexEdit ändern muss, um diesen Fehler zu umgehen, ist das offensichtlich nicht sehr effizient. Alex vor 10 Jahren 0

1 Antwort auf die Frage

4
Karan

JpegTran has now been updated by its developer and the edge truncation bug has been fixed, so no other app is required to accomplish my task.

... Please share with me where you got this updated version. I am having the same problem (it's so annoying I'm only 1 pixel short!), and I cannot find a version which does not truncate partial MCUs. Alex vor 10 Jahren 0
@Alex: Entschuldigung für die extrem verspätete Antwort, aber ich habe mich seit einiger Zeit nicht mehr hier angemeldet. Hoffentlich hilft dies anderen, auch wenn es für Sie zu spät ist. Die [JpegTran-Seite] (http://jpegclub.org/jpegtran/), auf die ich oben verwirrt habe, hat * zwei * Downloads für die EXE-Datei. Die in Abschnitt 1 ("* Neue Jpegtran-Skala verlustfreie Größenänderung *") ist ** NICHT ** die, die Sie hier möchten. Holen Sie sich stattdessen eine aus Abschnitt 3 ("* Verlustfreies Crop 'n' Drop (Ausschneiden und Einfügen) *"). Der verbesserte Drop-Code wurde der App am 05.10.2012 auf Vorschlag eines Kollegen hinzugefügt, der mit mir zusammenarbeitete. Karan vor 9 Jahren 1