AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi JPG-Datei drehen und speichern -> Verlust der Exif-Daten
Thema durchsuchen
Ansicht
Themen-Optionen

JPG-Datei drehen und speichern -> Verlust der Exif-Daten

Ein Thema von axelf98 · begonnen am 3. Sep 2005 · letzter Beitrag vom 22. Aug 2021
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.348 Beiträge
 
Delphi 12 Athens
 
#1

AW: JPG-Datei drehen und speichern -> Verlust der Exif-Daten

  Alt 6. Jul 2020, 18:37
Der zweite Teil verwirrt mich.
JPEG-Bilder enthalten eine Anweisung, wie sie zur richtigen Anzeige gedreht werden müssen. Z.B. Top left besagt, das Bild braucht nicht gedreht zu werden. http://sylvana.net/jpegcrop/exif_orientation.html
Jupp, z.B. der Windows-Image-Viewer stellt auch nur die Orientation in den Exif-Daten um, wenn man dort das Bild dreht.
Auch einige Kameras setzen diese Option, über einen Lagesensor.

Wird nur die Option geändert/gesetzt, dann wird erst bei Anzeige das Bild gedreht,
aber die eigentlichen Daten bleiben unverändert, also ist das somit 100% verlustfrei.

Wenn man das Bild "richtig" dreht, dann muß man ja die Pixel umherschieben, womit dann das Bild neu komprimiert/berechnet wird, was natürlich Verluste erzeugt.

Oder man versucht in den komprimierten Daten die Blöcke umzuorganiisieren und in der Codierung gleiche/ähnliche Blöcke in eine Version der gegrehten Ausrichtung zu ersetzen,
falls es da überhaupt möglich ist das 1:1 zu drehen.


Die JPEG-Implementation im Delphi kann das halt nicht.
Also müsstest du dir entweder eine andere Implementation besorgen. (vielleicht kann Windows das bereitstellen, wenn du TWICImage benutzt, oder du spielst mit GDI+ rum)
Oder du mußt selbst die Exif-Daten auswerten und dann das Bild im Canvas drehen, nach dem Laden der Datei.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 6. Jul 2020 um 18:40 Uhr)
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
570 Beiträge
 
Delphi 12 Athens
 
#2

AW: JPG-Datei drehen und speichern -> Verlust der Exif-Daten

  Alt 6. Jul 2020, 20:44
Wenn man das Bild "richtig" dreht, dann muß man ja die Pixel umherschieben, womit dann das Bild neu komprimiert/berechnet wird, was natürlich Verluste erzeugt.
Kann nicht dein Ernst sein, Himitsu. Seit Jahrzehnten ist der Algorithmus bekannt, mit dem man ein JPG verlustfrei drehen kann, sofern dies in 90°-Schritten geschieht (90°, 180° und 270°). Ich habe jetzt auf die Schnelle keine bessere Fundstelle gefunden als diese auf Seite 7. Alle anderen Grade gehen natürlich nicht verlustfrei, vermutlich meintest du das.

Warum der TE nicht eine der von mir genannten Möglichkeiten nimmt, erschließt sich mir nicht, ist aber seine Sache. Natürlich ist EXIFTool unübertroffen, aber für die allermeisten Aufgaben ein völliger Overkill, und man handelt sich ein externes Programm ein. Die einzige Aufgabe, wozu ich bis jetzt an EXIFTool gebunden bin, ist das Auslesen des Objektives. Schlichtes verlustfreies Drehen mache ich seit Jahren mit reinen Delphi-Bordmitteln - und noch einiges mehr.
  Mit Zitat antworten Zitat
jsp

Registriert seit: 9. Aug 2003
50 Beiträge
 
#3

AW: JPG-Datei drehen und speichern -> Verlust der Exif-Daten

  Alt 7. Jul 2020, 06:39
Hallo zusammen

ich werfe hier mal https://www.imageen.com/ in die Runde.
Kostet zwar was... Ich war immer sehr zufrieden damit.

Gruss, Jörn
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.348 Beiträge
 
Delphi 12 Athens
 
#4

AW: JPG-Datei drehen und speichern -> Verlust der Exif-Daten

  Alt 7. Jul 2020, 07:42
Seit Jahrzehnten ist der Algorithmus bekannt,
Ich hatte mal vor 'ner Weile versucht rauszufinden wie die Blöcke codiert sind und hab dHäfte schonwieder vergessen, aber mir ist so als wenn es nicht für alles eine 1:1 Variante in gedrehter Ausrichtung gab,
aber ich darf mich da auch gern getäuscht haben.

Hab den Artikel jetzt auch nur schnell überflogen und schau später nochmal genauer rein, aber selbst im Abschnitt "Results of lossless transcoding" sieht es so aus, als wenn es einen "winzigen" Unterschied gibt, womit des demnach doch nicht ganz "verlustlos" ist.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
711 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: JPG-Datei drehen und speichern -> Verlust der Exif-Daten

  Alt 7. Jul 2020, 08:27
Hab den Artikel jetzt auch nur schnell überflogen und schau später nochmal genauer rein, aber selbst im Abschnitt "Results of lossless transcoding" sieht es so aus, als wenn es einen "winzigen" Unterschied gibt, womit des demnach doch nicht ganz "verlustlos" ist.
Ja, es gibt einen Unterschied. Und zwar wenn die Dimensionen des Bildes nicht durch 8 teilbar sind. Dann sind am Rand Blöcke die nicht mit gedreht werden können. Die werden dann abgeschnitten bzw. weggelassen.
IrfanView weist in den Einstellungen für das Rotationstool auch drauf hin.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
Willie1

Registriert seit: 28. Mai 2008
696 Beiträge
 
Delphi 10.1 Berlin Starter
 
#6

AW: JPG-Datei drehen und speichern -> Verlust der Exif-Daten

  Alt 7. Jul 2020, 10:28
Ich drehe JPEG's seit Jahren mit GDI+. Das geht schnell, ist verlustfrei und die Meta-Daten bleiben erhalten. Ich programmiere nur in der Windows-Welt.
W.
Gut hören kann ich schlecht, schlecht sehen kann ich gut - Ersteres stimmt nicht, das zweite schon.
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
570 Beiträge
 
Delphi 12 Athens
 
#7

AW: JPG-Datei drehen und speichern -> Verlust der Exif-Daten

  Alt 7. Jul 2020, 10:29
Die werden dann abgeschnitten bzw. weggelassen.
Kommt auf das Programm an. Es gibt auch welche - weiß jetzt nicht, ob IrfanView dazugehört - die bieten an, entweder den über den 8-Pixel-Block hinausgehenden Rand abzuschneiden oder ihn (und nur ihn) verlustbehaftet mitzuverarbeiten.

ich werfe hier mal https://www.imageen.com/ in die Runde.
ImageEn ist ein Hammer, allerdings teuer und meiner Meinung nach in manchen Routinen nicht das Schnellste. Wenn man seinem Programm Bildbearbeitung verpassen will, dann hat man mit ImageEn eine Luxuslösung. ImageEn ist übrigens ein Programm, das die oben genannte Option anbietet.

doch nicht ganz "verlustlos" ist.
Bis auf die 8-Pixel-Grenze lassen sich die Scanlines (das ist jetzt leider sehr laienhaft ausgedrückt) einfach "umsortieren", das ist vollständig verlustfrei. Interessant ist, dass ein so "gedrehtes" JPG nicht mehr die exakt gleiche Größe hat wie das ungedrehte Bild. Es gibt auch irgendwo eine Erklärung, warum das so ist.

Allerdings hat die verlustfreie Drehung unter Umständen ein paar Nebenwirkungen, über die der Arzt oder Apotheker nicht informiert. Wie der TE schon bemerkt hat, geht bei manchen Programmen die EXIF-Sektion verloren. Das sind natürlich keine akzeptablen Programme. Schon etwas tiefergehender ist, dass nach der Drehung die Werte für Breite und Höhe in den EXIF-Daten vertauscht werden müssen; das machen natürlich auch nicht alle. Ganz doll ist, dass manchmal - und zwar auch bei IrfanView - eingebettete Vorschaubilder einfach gekappt werden. Die Sony-Systemkameras zum Beispiel betten in alle JPG nicht nur das "normale" kleine Vorschaubild (Thumbnail auf Deutsch), sondern noch ein weiteres Full HD-Bild von 1920x1080 Pixel ein (die JPEG-Spezifikation erlaubt ja beliebig viele davon). Einmal gedreht - weg isses! Die allermeisten Fotografen ahnen nicht mal, dass überhaupt eins da ist; sie bemerken allenfalls, dass die Datei nach dem (ersten!) Drehen plötzlich viel kleiner ist als vorher und schließen messerscharf, dass die Drehung nicht verlustfrei war. Wer das weiß und die großen Bilder sowieso nicht nutzt (es gibt praktisch kein Programm, das zusätzliche Vorschaubilder anzeigt), dann kann man seine Sony-Bilder durch zweimaliges verlustfreies Drehen hin und zurück platzsparend verkleinern.

Auch noch für Irritation bei vielen Anfänger-Drehern sorgt, dass das Orientation Tag nach jedem beliebigen Drehen immer auf 1 (Top Left) zurückgesetzt wird, auch wenn das Bild zum Beispiel auf hochkant gedreht wird. Mit etwas Nachdenken kommt man darauf, warum das so sein muss.
Für besonders viel Irritation sorgt es, wenn ein Drehprogramm das Orientation Tag auf 1 zurückgesetzt, aber die Werte für Breite und Höhe nicht angepasst hat. Dann zeigt natürlich auch der Explorer das Bild falsch an und dann ist das Rätselraten groß: "Mein Bild wird überhaupt nicht gedreht!".

Und wem man auch noch Beachtung schenken sollte, ist das Dateidatum (d.h. alle drei). Die sollten nach dem Drehen wieder zurückgesetzt werden, eleganterweise auf das EXIF-Datum.

[EDIT] Da mich das Thema - wie gesagt - laufend interessiert, habe ich mal Test mit drei Codevarianten gemacht: NativeJPG, JPEGEX und FreeImage. 10 JPG von durchschnittlich 6 MB wurden um 90° gedreht. Bei allen drei blieben die EXIF-Informationen erhalten. NativeJPG benötigte im Durchschnitt 1.100 msec, die beiden anderen um die 300 für das reine Drehen.

Nebenerkenntnis: Das "Kappen" der eingebetteten Vorschaudatei konnte ich - auch bei IrfanView - nicht (mehr) beobachten. Den Algorithmus des verlustfreien Drehens kann man übrigens in sdJpegLossless.pas studieren.

Ich drehe JPEGs seit Jahren mit GDI+. Das geht schnell, ist verlustfrei und die Meta-Daten bleiben erhalten.
Wie/womit genau machst du das? Das würde mich interessieren.

Geändert von Benmik ( 7. Jul 2020 um 16:20 Uhr)
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
570 Beiträge
 
Delphi 12 Athens
 
#8

AW: JPG-Datei drehen und speichern -> Verlust der Exif-Daten

  Alt 8. Jul 2020, 10:55
Hier noch die Verwendung von GDI+. Nur einfaches Beispiel, ohne Ressourcenschutz oder Ähnliches. Leider bietet die Save-Procedure nicht die Option des Überschreibens, daher ein bisschen Nachbau. GDI+ ist sehr schnell. Zu beachten ist, dass hier die Blockgröße 16 Pixel beträgt, Höhe/Breite also ein Vielfaches von 16 sein müssen.
Frustrierend ist, dass GDI+ als 32-Bit-DLL natürlich wieder mal nicht in 64-Bit-Anwendungen benutzt werden kann.
Delphi-Quellcode:
uses ... GDIPAPI, GDIPOBJ,GDIPUTIL;

procedure DreheMitGDIPlus1;
Var i:integer;
  DatListe:TStringDynArray;
  GPImage: TGPImage;
  EncoderCLSID: TGUID;
  Ergebnis : Status;
  TempDatname:string;
const
  Verz = 'C:\Test\';
begin
  DatListe := TDirectory.GetFiles(Verz,'*.jpg');
  GetEncoderClsid('image/jpeg', EncoderCLSID);
  For i := 0 to High(DatListe) do begin
    GPImage := TGPImage.Create(DatListe[i]);
    GPImage.RotateFlip(Rotate90FlipNone);
    TempDatname := TPath.ChangeExtension(DatListe[i],'$$$');
    Ergebnis := GPImage.Save(TempDatname,EncoderCLSID);
    GPImage.Free;
    If Ergebnis = Ok then begin
      If DeleteFile(DatListe[i])
        then RenameFile(TempDatname,DatListe[i])
        else DeleteFile(TempDatname);
    end;
  end;
end;
Die nachfolgende Version ist die "volle". An ihr ist besonders interessant, dass sie nicht nur selbständig ermittelt, ob das JPG überhaupt gedreht werden muss, sondern auch den Zugriff auf weitere GDI-Funktionen bietet. Auch kann außer dem PropertyTagOrientation noch eine Vielzahl von weiteren EXIF-Markern ausgelesen werden.
Delphi-Quellcode:
uses ... GDIPAPI, GDIPOBJ,GDIPUTIL;

procedure DreheMitGDIPlus2;
Var i:integer;
  DatListe:TStringDynArray;
  GPImage: TGPImage;
  PPropItem: PPropertyItem;
  BufferSize: Cardinal;
  Orientation: Byte;
  RotateBy: EncoderValue;
  EncoderCLSID: TGUID;
  EncoderParams: TEncoderParameters;
  EncoderTransformValue:integer;
  Ergebnis : Status;
  TempDatname:string;
const
  Verz = 'C:\Test\';
begin
  DatListe := TDirectory.GetFiles(Verz,'*.jpg');
  GetEncoderClsid('image/jpeg', EncoderCLSID);
  FillChar(EncoderParams, SizeOf(EncoderParams), 0);
  EncoderParams.Count := 1;
  EncoderParams.Parameter[0].Guid := EncoderTransformation;
  EncoderParams.Parameter[0].Type_ := EncoderParameterValueTypeLong;
  EncoderParams.Parameter[0].NumberOfValues := 1;
  For i := 0 to High(DatListe) do begin
    GPImage := TGPImage.Create(DatListe[i]);
    BufferSize := GPImage.GetPropertyItemSize(PropertyTagOrientation);
    If BufferSize > 0 then begin
      GetMem(PPropItem, BufferSize);
      Try
        GPImage.GetPropertyItem(PropertyTagOrientation, BufferSize, PPropItem);
        Orientation := PByte(PPropItem.value)^;
        case Orientation of
          3: RotateBy := EncoderValueTransformRotate180;
          6: RotateBy := EncoderValueTransformRotate90;
          8: RotateBy := EncoderValueTransformRotate270;
          else Continue;
        end;
        If (Orientation in [3,6,9]) then begin
          EncoderTransformValue := Ord(RotateBy);
          EncoderParams.Parameter[0].Value := @EncoderTransformValue;
          TempDatname := TPath.ChangeExtension(DatListe[i],'$$$');
          Ergebnis := GPImage.Save(WideString(TempDatname),EncoderCLSID,@EncoderParams);
          GPImage.Free;
          If Ergebnis = Ok then begin
            If DeleteFile(DatListe[i])
              then RenameFile(TempDatname,DatListe[i])
              else DeleteFile(TempDatname);
          end;
        end;
      Finally
        FreeMem(PPropItem);
      end;
    end;
  end;
end;

Geändert von Benmik ( 8. Jul 2020 um 14:50 Uhr) Grund: Blockgröße 16 Pixel
  Mit Zitat antworten Zitat
Willie1

Registriert seit: 28. Mai 2008
696 Beiträge
 
Delphi 10.1 Berlin Starter
 
#9

AW: JPG-Datei drehen und speichern -> Verlust der Exif-Daten

  Alt 9. Jul 2020, 18:10
Schlichtes verlustfreies Drehen mache ich seit Jahren mit reinen Delphi-Bordmitteln - und noch einiges mehr.
Hallo, dann gehen die Meta-Daten verloren.
Mir fällt auf, dass beim Drehen mit GDI+ das eingebettete Thumbnail nicht mit gedreht wird und außerdem wird das Orientation-Tag nicht angepasst. Der erste Fehler ist ein Schönheitsfehler, der zweite schon ärgerlich.
Willie.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz