(CodeLib-Manager)
Registriert seit: 10. Jun 2002
4.648 Beiträge
Delphi XE Professional
|
AW: Bildformat anhand Header erkennen
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)
|
|
Zitat
|