Einzelnen Beitrag anzeigen

Benutzerbild von toms
toms
(CodeLib-Manager)

Registriert seit: 10. Jun 2002
4.648 Beiträge
 
Delphi XE Professional
 
#9

AW: Bildformat anhand Header erkennen

  Alt 31. Okt 2010, 07:00
TBitmapFileHeader ist nur für Datein mit Typ "BM" gedacht. TBitmapFileHeader.bfType gibt auch nur immer 2 bytes zurück.
Die Signaturen von JPEG etc. sind jedoch länger und so werden die Dateien unter Umständen nicht korrekt erkannt. Somit bevorzuge ich meine Variante, auch wenn sie etwas länger ist.

Anbei noch eine leicht abgeänderte Variante:

Delphi-Quellcode:
type
  TImageType = (ifUnknown, ifJPG, ifGIF, ifBMP, ifPNG, ifPSD, ifTIF, ifWMF);

type
  TImageSignature = record
    ImgType: TImageType;
    ImgName: string;
    ImgSig: AnsiString;
  end;

function GetImageType(FileName: string): TImageSignature;
const
  MAX_SIGNATURES = 8;

  Signatures: array[0..MAX_SIGNATURES] of TImageSignature = (
    (ImgType: ifGIF; ImgName: 'Image/GIF'; ImgSig: #$47#$49#$46#$38),
    (ImgType: ifJPG; ImgName: 'Image/JPEG'; ImgSig: #$FF#$D8#$FF#$E0),
    (ImgType: ifJPG; ImgName: 'Image/JPEG'; ImgSig: #$FF#$D8#$FF#$E1),
    (ImgType: ifPNG; ImgName: 'Image/PNG'; ImgSig: #$89#$50#$4E#$47),
    (ImgType: ifBMP; ImgName: 'Image/BMP'; ImgSig: #$42#$4D),
    (ImgType: ifTIF; ImgName: 'Image/TIFF'; ImgSig: #$49#$49#$2A),
    (ImgType: ifTIF; ImgName: 'Image/TIFF'; ImgSig: #$4D#$4D#$00),
    (ImgType: ifWMF; ImgName: 'Image/WMF'; ImgSig: #$D7#$CD#$C6#$9A),
    (ImgType: ifPSD; ImgName: 'Image/PSD'; ImgSig: #$38#$42#$50#$53));

  function CheckImageSignature(AStream: TStream; Signature: AnsiString; Offset:
    Integer): Boolean;
  var
    Buffer: AnsiString;
    Count: Integer;
    BytesRead: Integer;
  begin
    Result := False;
    try
      Count := Length(Signature);
      AStream.Position := Offset;
      SetLength(Buffer, Count);
      BytesRead := AStream.Read(Buffer[1], Count);
      Result := (BytesRead = Count) and (Buffer = Signature);
    except
    end;
  end;

var
  Stream: TFileStream;
  MemStr: TMemoryStream;
  i: Integer;
begin
  FillChar(Result, SizeOf(Result), 0);
  Result.ImgType := ifUnknown;
  Stream := TFileStream.Create(FileName, fmOpenRead);
  try
    MemStr := TMemoryStream.Create;
    try
      MemStr.CopyFrom(Stream, 5);
      if MemStr.Size > 4 then
      begin
        for i := Low(Signatures) to High(Signatures) do
        begin
          if CheckImageSignature(MemStr, Signatures[i].ImgSig, 0) then
          begin
            Result.ImgType := Signatures[i].ImgType;
            Result.ImgName := Signatures[i].ImgName;
            Result.ImgSig := Signatures[i].ImgSig;
            Break;
          end;
        end;
      end;
    finally
      MemStr.Free;
    end;
  finally
    Stream.Free;
  end;
end;


procedure TForm1.FormCreate(Sender: TObject);
var
  FileName: string;
  ImgSig: TImageSignature;
begin
  if OpenDialog1.Execute then
  begin
    FileName := OpenDialog1.FileName;
    ImgSig := GetImageType(FileName);
    case ImgSig.ImgType of

      ifPNG:
        begin
          //...
        end;

      ifJPG:
        begin
         //...
        end;

      ifGif:
        begin
         //...
        end;

      ifBMP:
        begin
         //...
        end;
    end;
  end;
end;
Thomas

Geändert von toms (31. Okt 2010 um 07:40 Uhr)
  Mit Zitat antworten Zitat