![]() |
Sichere Erkennung von PNG bzw. JPG?
Ich treffe immer wieder auf Bilddateien, die nicht dem Typ der Dateierweiterung entsprechen. Also Bild ist ein JPEG, heißt aber "Bild.PNG" oder Bild ist ein PNG, heißt aber "Bild.JPG". Programme wie IrfanView machen mich darauf aufmerksam und bieten an, die Datei passend umzubenennen. Wenn ich selbst versuche, die Datei per TPNGImage/TJPEGImage zu laden, wirfts mir eine Exception. Gibt es eine fertige Funktion irgendwo in den Tiefen der Delphi Bibliothek, die die Unterscheidung (nach dem Dateianfang) machen kann oder muss ich da selbst ran?
|
AW: Sichere Erkennung von PNG bzw. JPG?
"magic bytes" ist das Schlagwort.
Hier eine Liste der Signaturen von bekannten Dateitypen ![]() Der Delphi-Ladeprozess geht über den Dateinamen. Du musst also entweder selbst die Datei in einen Memory-Stream zuerst laden oder über eine Temporäre Datei mit richtiger Extension arbeiten. |
AW: Sichere Erkennung von PNG bzw. JPG?
In neueren Delphis haben die Grafikklassen das glaube ich selbst.
Ansonsten:
Delphi-Quellcode:
type TImageFormat = (unknown, BMP, GIF, JPG, PNG);
function GetImageFormat(Stream: TStream): TImageFormat; var Memory: array[0..8] of Byte; begin Result := unknown; try if Stream.Size < 10 then Exit; Stream.Position := 0; Stream.Read(Memory, 9); case Memory[0] of 66: if Memory[1] = 77 then // BM: Bitmap Result := BMP; 137: if Memory[1] = 80 then // ‰PNG: PNG if Memory[2] = 78 then if Memory[3] = 71 then if Memory[4] = 13 then if Memory[5] = 10 then if Memory[6] = 26 then if Memory[7] = 10 then Result := PNG; 71: if Memory[1] = 73 then // GIF8...a if Memory[2] = 70 then if Memory[3] = 56 then if Memory[5] = 97 then case Memory[4] of 55: Result := GIF; // 7: GIF, old 57: Result := GIF; // 9: GIF, new end; 255: if Memory[1] = 216 then // ÿØ: JPEG Result := JPG; end; except end; Stream.Position := 0; end; function LoadImageFromStream(Target: TPersistent; Stream: TStream): Boolean; var GraphicClass: TGraphicClass; Graphic: TGraphic; begin Result := False; case GetImageFormat(Stream) of BMP: GraphicClass := Graphics.TBitmap; PNG: GraphicClass := TPNGImage; JPG: GraphicClass := TJPEGImage; GIF: GraphicClass := TGIFImage; else raise EInvalidGraphic.CreateFmt(SInvalidImage, []); end; if not (GraphicClass = nil) then begin Graphic := GraphicClass.Create; try Graphic.LoadFromStream(Stream); Target.Assign(Graphic); Result := True; finally Graphic.Free; end; end; end; |
AW: Sichere Erkennung von PNG bzw. JPG?
Bei den neueren Delphi-Versionen gibt es das TWICImage (Unit VCL.Graphics.pas). Das macht bei LoadfromFile() keinen Abgleich über die Dateiendung, sondern geht über den Dateiinhalt und lädt automatisch den passenden Decoder.
Delphi-Quellcode:
wird dann z.B. korrekt geladen, auch wenn die Dateiendung nicht passt.
WicImage := TWICImage.Create
WicImage.LoadFromFile('EinPNGBild.jpg); Ansonsten halt selber machen, siehe oben. ;-) |
AW: Sichere Erkennung von PNG bzw. JPG?
Ich mach das immer so:
Delphi-Quellcode:
const
jpg: array[0..2] of byte = ($FF, $D8, $FF); png: array[0..2] of byte = ($89, $50, $4E); gif: array[0..2] of byte = ($47, $49, $46); ... var buf: array [0..2] of byte; ... begin ... stream.Seek(0, soFromBeginning); // stream.Position := 0; stream.Read(buf, SizeOf(buf)); if (stream.Size > 0) then begin if CompareMem(@buf, @jpg, SizeOf(buf)) then begin bildtyp := btJPEG // JPG end else if CompareMem(@buf, @png, SizeOf(buf)) then begin bildtyp := btPNG // PNG end else if CompareMem(@buf, @gif, SizeOf(buf)) then begin bildtyp := btGIF // GIF end else result := false; end; stream.Seek(0, soFromBeginning); ... |
AW: Sichere Erkennung von PNG bzw. JPG?
Danke an alle, das hilft mir weiter.
|
AW: Sichere Erkennung von PNG bzw. JPG?
Ich hatte das Thema "Magic Numbers" und auch File-Handling mit Streams seit Jahren auf dem Zettel.
Die obigen Lösungsvorschläge waren für mich also ein gegebener Anlass, mich damit mal etwas intensiver zu befassen und hab' mir kurzerhand jeweils ein Beispielprojekt zusammengebaut. Beides läuft. ...man muß also manchmal nur in seinem Leben abwarten können ;-) |
AW: Sichere Erkennung von PNG bzw. JPG?
vllt noch so als tipp: häufige stolperfalle, stream vergessen zurückzusetzen
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:33 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