AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Sichere Erkennung von PNG bzw. JPG?
Thema durchsuchen
Ansicht
Themen-Optionen

Sichere Erkennung von PNG bzw. JPG?

Ein Thema von Frickler · begonnen am 15. Mär 2022 · letzter Beitrag vom 17. Mär 2022
Antwort Antwort
Frickler

Registriert seit: 6. Mär 2007
Ort: Osnabrück
589 Beiträge
 
Delphi XE6 Enterprise
 
#1

Sichere Erkennung von PNG bzw. JPG?

  Alt 15. Mär 2022, 18:32
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?
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.196 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Sichere Erkennung von PNG bzw. JPG?

  Alt 15. Mär 2022, 18:55
"magic bytes" ist das Schlagwort.
Hier eine Liste der Signaturen von bekannten Dateitypen
https://en.wikipedia.org/wiki/List_of_file_signatures

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.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.051 Beiträge
 
Delphi 2009 Professional
 
#3

AW: Sichere Erkennung von PNG bzw. JPG?

  Alt 15. Mär 2022, 19:13
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;
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
878 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Sichere Erkennung von PNG bzw. JPG?

  Alt 15. Mär 2022, 19:21
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:
WicImage := TWICImage.Create
WicImage.LoadFromFile('EinPNGBild.jpg);
wird dann z.B. korrekt geladen, auch wenn die Dateiendung nicht passt.

Ansonsten halt selber machen, siehe oben.
The angels have the phone box.
  Mit Zitat antworten Zitat
completestranger

Registriert seit: 7. Okt 2018
25 Beiträge
 
#5

AW: Sichere Erkennung von PNG bzw. JPG?

  Alt 16. Mär 2022, 08:29
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);
  ...
  Mit Zitat antworten Zitat
Frickler

Registriert seit: 6. Mär 2007
Ort: Osnabrück
589 Beiträge
 
Delphi XE6 Enterprise
 
#6

AW: Sichere Erkennung von PNG bzw. JPG?

  Alt 17. Mär 2022, 13:26
Danke an alle, das hilft mir weiter.
  Mit Zitat antworten Zitat
TSchnuckenbock

Registriert seit: 20. Jul 2017
Ort: Lüneburger Heide
71 Beiträge
 
Delphi XE5 Professional
 
#7

AW: Sichere Erkennung von PNG bzw. JPG?

  Alt 17. Mär 2022, 14:43
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
  Mit Zitat antworten Zitat
completestranger

Registriert seit: 7. Okt 2018
25 Beiträge
 
#8

AW: Sichere Erkennung von PNG bzw. JPG?

  Alt 17. Mär 2022, 15:35
vllt noch so als tipp: häufige stolperfalle, stream vergessen zurückzusetzen
  Mit Zitat antworten Zitat
Alt 13. Apr 2022, 22:16     Erstellt von JonahJatson
Dieser Beitrag wurde von TBx gelöscht. - Grund: Verdacht auf SPAM und den damit verbundenen verschwenderischen Umgang von wertvollen Bits und Bytes
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 23:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz