Einzelnen Beitrag anzeigen

e-gon

Registriert seit: 7. Jul 2003
Ort: Stuttgart
156 Beiträge
 
Delphi 6 Enterprise
 
#10

AW: EXIF auf anderes JPEG übertragen

  Alt 6. Nov 2013, 10:08
Hallo ASM,

vielen Dank für Deine Unterstützung! Mit dem Problem der Positionierung im Stream hast Du grundsätzlich recht. Ich habe allerdings festgestellt, wenn man unmittelbar vor dem CopyFrom den Seek-Befehl ausführt, funktioniert das Kopieren ab der Seek-Position.

Mein Problem war übrigens ein Leichtsinnsfehler! Habe beim zweiten Read statt 4 nur 3 Zeichen gelesen! Das habe ich aber erst nach viel Debuggen und Hexen herausbekommen!
Immerhin, jetzt scheint es zu funktionieren!

Falls es mal jemand braucht, hier nochmals der finale Code:

Delphi-Quellcode:
procedure TForm1.CopyEXIF(const FileNameEXIFSource, FileNameEXIFTarget: string);
const
  M_JFIF = $E0;
  M_EXIF = $E1;
var
  MSSource, MSTarget: TMemoryStream;
  FS: TFileStream;
  TargetStartPos, SourceEndPos: Longint;
  Buf: Array [0..3] of Byte;
begin
  MSTarget := TMemoryStream.Create;
  try
// 4. Lies dann Deine veränderte jpeg-Datei in den MemoryStream.
    TargetStartPos := 2;
    MSTarget.LoadFromFile(FileNameEXIFTarget);
    MSTarget.Seek(TargetStartPos, soFromBeginning);
    MSTarget.Read(Buf, 4);
    if Buf[1] = M_JFIF then begin
      TargetStartPos := TargetStartPos+(Buf[2]*256)+Buf[3]+2;
      MSTarget.Seek(TargetStartPos, soFromBeginning);
      MSTarget.Read(Buf, 4);
    end;
    if (Buf[1] <> M_EXIF) or
       (MessageDLG('Die Datei '''+FileNameEXIFTarget+''' hat selbst ein EXIF! Soll dieser wirklich überschrieben werden?',
                   mtConfirmation, [mbYes,mbNo], 0) = mrYes) then begin
      if Buf[1] = M_EXIF then TargetStartPo s:= TargetStartPos+(Buf[2]*256)+Buf[3]+2;

      MSSource := TMemoryStream.Create;
      try
// 1. Lies aus Deiner originalen jpeg-Datei die Größe der EXIF-Struktur aus (steht in den Bytes unmittelbar nach dem EXIF-StartTag "FFE1" und reicht bis zur Kennung "786969660000" = "Exif").
        SourceEndPos := 2;
        MSSource.LoadFromFile(FileNameEXIFSource);
        MSSource.Seek(SourceEndPos, soFromBeginning);
        MSSource.Read(Buf, 4);
        if Buf[1] = M_EXIF then SourceEndPos := SourceEndPos+(Buf[2]*256)+Buf[3]+2;
// 2. Lies die originale jpeg-Datei in einen MemoryStream. Setze die Größe des MemoryStreams zurück auf die Größe der EXIF-Struktur zuzüglich der 4 führenden Kennbytes der jpeg-Datei (FFD8 und FFE1).
        MSSource.SetSize(SourceEndPos);

// 3. Übertrage den MemoryStream in den FileStream, der Deine neue jpeg-Datei anlegt, welche sowohl Dein verändertes jpeg-Bild als auch die ursprüngliche EXIF-Information aufnehmen soll.
        FS := TFileStream.Create(FileNameEXIFTarget, fmCreate or fmShareExclusive);
        try
          MSSource.SaveToStream(FS);

// 5. Setze den Pointer des MemoryStreams auf die Position $02 (also ab dem 3.Byte, d.h. ohne die JPEG-Kennung "FFD8" der zweiten Datei) und übertrage den MemoryStream ab dieser Position in den zuvor begonnenen Filestream.
          MSTarget.Seek(TargetStartPos, soFromBeginning);
          FS.CopyFrom(MSTarget, MSTarget.Size-TargetStartPos);
        finally
          FS.Free;
        end;
      finally
        MSSource.Free;
      end
    end;
  finally
    MSTarget.Free;
  end;
end;
  Mit Zitat antworten Zitat