![]() |
AW: wie art der daten in blob erkennen?
@himitsu, ich kam mit Deiner Art leider nicht ganz zurecht aber habe es recht gut optimiert finde ich
Delphi-Quellcode:
@schorch666, die Idee den User entscheiden zu lassen mag ich, meine Idee basiert halt auf Signaturen um etwas automatisch anzukicken, wobei ich halt extrem eingeschränkt bin auf die paar Signaturen die man der Definition entnehmen kann, eine Klasse basierend auf dem Wiki wäre halt eine Variante einer möglichen automatisierung, wobei dann immer noch das zutun vom User notwendig sein kann um was-auch-immer-für-ein-format mit was-auch-immer zu öffnen.
program Project12;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Classes; {$SCOPEDENUMS ON} type TImageFormat = (Unknown, BMP, GIF, TIFF, JPEG, PNG, ICO); {$SCOPEDENUMS OFF} type TSignature = packed record Format: Integer; Offset: Integer; Signature: array of Integer; end; TSignatures = array of TSignature; function GetSignatureList: TSignatures; begin SetLength(Result, 14); Result[0].Format := Ord(TImageFormat.JPEG); Result[0].Offset := 0; Result[0].Signature := [$FF, $D8, $FF, $DB]; Result[1].Format := Ord(TImageFormat.JPEG); Result[1].Offset := 0; Result[1].Signature := [$FF, $D8, $FF, $E0, $00, $10, $4A, $46]; Result[2].Format := Ord(TImageFormat.JPEG); Result[2].Offset := 0; Result[2].Signature := [$49, $46, $00, $01]; Result[3].Format := Ord(TImageFormat.JPEG); Result[3].Offset := 0; Result[3].Signature := [$FF, $D8, $FF, $EE]; Result[4].Format := Ord(TImageFormat.JPEG); Result[4].Offset := 0; Result[4].Signature := [$FF, $D8, $FF, $E1, -1, -1, $45, $78]; Result[5].Format := Ord(TImageFormat.JPEG); Result[5].Offset := 0; Result[5].Signature := [$69, $66, $00, $00]; Result[6].Format := Ord(TImageFormat.JPEG); Result[6].Offset := 0; Result[6].Signature := [$FF, $D8, $FF, $E0]; Result[7].Format := Ord(TImageFormat.PNG); Result[7].Offset := 0; Result[7].Signature := [$89, $50, $4E, $47, $0D, $0A, $1A, $0A]; Result[8].Format := Ord(TImageFormat.GIF); Result[8].Offset := 0; Result[8].Signature := [$47, $49, $46, $38, $37, $61]; Result[9].Format := Ord(TImageFormat.GIF); Result[9].Offset := 0; Result[9].Signature := [$47, $49, $46, $38, $39, $61]; Result[10].Format := Ord(TImageFormat.BMP); Result[10].Offset := 0; Result[10].Signature := [$42, $4D]; Result[11].Format := Ord(TImageFormat.ICO); Result[11].Offset := 0; Result[11].Signature := [$00, $00, $01, $00]; Result[12].Format := Ord(TImageFormat.TIFF); Result[12].Offset := 0; Result[12].Signature := [$49, $49, $2A, $00]; Result[13].Format := Ord(TImageFormat.TIFF); Result[13].Offset := 0; Result[13].Signature := [$4D, $4D, $00, $2A]; end; function GetMaxSignatureSize(const ASignatures: TSignatures): Integer; var i: Integer; begin Result := 0; for i := Low(ASignatures) to High(ASignatures) do if (Length(ASignatures[i].Signature) > Result) then Result := Length(ASignatures[i].Signature); end; function CompareBytes(const AData: TBytes; const AOffset: Integer; const ASignature: array of Integer): Boolean; var i: Integer; begin Result := False; if (Length(AData) < (AOffset + Length(ASignature))) then Exit; for i := Low(ASignature) to High(ASignature) do if (ASignature[i] <> -1) then if (AData[i + AOffset] <> ASignature[i]) then Exit; Result := True; end; function GetBytesFormat(const AData: TBytes): TImageFormat; var Signatures: TSignatures; i: Integer; begin Signatures := GetSignatureList; for i := Low(Signatures) to High(Signatures) do if CompareBytes(AData, Signatures[i].Offset, Signatures[i].Signature) then Exit(TImageFormat(Signatures[i].Format)); Result := TImageFormat.Unknown; end; function FilePartToBytes(const AFilename: string; const AOffset, ASize: Integer): TBytes; var FileStream: TFileStream; begin SetLength(Result, 0); FileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite); try if (FileStream.Size < (AOffset + ASize)) then Exit; SetLength(Result, ASize); FileStream.Position := AOffset; FileStream.ReadBuffer(Result[0], ASize); finally FileStream.Free; end; end; var Data: TBytes; begin try if ParamCount > 0 then if FileExists(ParamStr(1)) then begin Data := FilePartToBytes(ParamStr(1), 0, GetMaxSignatureSize(GetSignatureList)); case GetBytesFormat(Data) of TImageFormat.Unknown: WriteLn('Unknown'); TImageFormat.JPEG: WriteLn('JPEG'); TImageFormat.BMP: WriteLn('BMP'); TImageFormat.PNG: WriteLn('PNG'); TImageFormat.GIF: WriteLn('GIF'); TImageFormat.TIFF: WriteLn('TIFF'); TImageFormat.ICO: WriteLn('ICO'); end; ReadLn; end; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
AW: wie art der daten in blob erkennen?
Das Casten der TSignature war ja nur, weil ich es in einem Byte gespeichert hab.
Im Record kannst da den richtigen Typ benutzen. Bei DatenRecords erstelle ich mir gern einen/mehrere Constuctor, um sie direkt einzeilig füllen zu können, auch direkt an Varioable/Property/Parameter übergebbar. Quasi ![]() ![]() ![]() ![]() Schön wäre bestimmt es, wenn Emba hier den Constructor implitit für Casts benutzen würde, also
Delphi-Quellcode:
alternativ zu
TSignature(...)
Delphi-Quellcode:
.
TSignature.Create(...)
Delphi-Quellcode:
Ja, der Code wird so weniger optimal, aber vom Code her wird es teilweise schöner.
TSignature = packed record
Format: TSignature; Offset: Integer; Signature: array of Byte; constructor Create(AFormat: TSignature; AOffset: Integer; ASignature: array of Byte); end; TSignatures = array of TSignature; function GetSignatureList: TSignatures; begin { Result := nil; Result := Result + [TSignature.Create(TImageFormat.JPEG, 0, [$FF, $D8, $FF, $DB])]; Result := Result + [TSignature.Create(TImageFormat.JPEG, 0, [$FF, $D8, $FF, $E0, $00, $10, $4A, $46])]; ... } Result := [ TSignature.Create(TImageFormat.JPEG, 0, [$FF, $D8, $FF, $DB]), TSignature.Create(TImageFormat.JPEG, 0, [$FF, $D8, $FF, $E0, $00, $10, $4A, $46]), ... ]; end; Man könnte noch schauen, ob es mit einem INLINE; besser wird. Delphi kennt ja seit 'ner Weile string-like Operatoren, wie man sie von Strings kennt, wie z.B. das
Delphi-Quellcode:
.
+
|
AW: wie art der daten in blob erkennen?
schoenen sonntag @ALL,
ich habs jetzt so geloest, dass der/die/das user: - einmal die moeglichkeit hat, mittels "speichern unter" "sein" dateiformat auszuwaehlen. und dann kann er die datei mittels doppelklick selber im entsprechenden "viewer" oeffnen - und andererseits (fuer die schnelle loesung) auswaehlen kann "als grafik anzeigen" oder "als text anzeigen", denn dem TImage ist es egal, ob die datei ein suffix hat - wird entweder angezeigt oder eben nicht. und je nachdem, was er/sie/es auswaehlt, wird halt eine vorschau in einem TImage gezeigt oder in einem memo.. das muss jetzt erstmal schicken. P.S.: hat jemand ne idee, wie ich .pdfs/word/excel - zumindest aber .pdf's anzeigen koennte? also tks... ...de Schorsch |
AW: wie art der daten in blob erkennen?
Zitat:
Wenn die so erzeugten Dateien nicht auf der Platte bleiben sollen, nachdem der Benutzer sie sich angesehen hat, kann man die Datei per API ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:59 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