![]() |
Datenbank: mysql • Version: 10 • Zugriff über: unidac
wie art der daten in blob erkennen?
Moin @ALL,
ich baue hier gerade einen data-editor und komme jetzt zu den blobs. und da das dann so eine art "blob-editor" wird, weiss ich also vorher nicht, um welche art von daten es sich bei einem jeweiligen blob-inhalt handelt. da ich aber eine art vorschau realisieren will, muesste ich das eben wissen... ich habe gelesen, dass man das in den ersten bytes erkennen koennte, aber da muesste ich ja ne dicke liste fuehren. auch habe ich ueberlegt, ob ich den krempel in die zwischenablage kopiere und mittels TClipboard checke - finde ich aber unelegant. und weil ich auch hier im forum leider nix gefunden habe, werfe ich das mal in die runde... hat jemand ne idee von euch?? ware super... ...de Schorsch |
AW: wie art der daten in blob erkennen?
Ja, die dicke Liste ist hier:
![]() Ist vermutlich nicht die neuste Datei, aber suche auch gerne mal nach libmagic. oder vielleicht auch ![]() |
AW: wie art der daten in blob erkennen?
Zitat:
![]() Bis bald... Thomas |
AW: wie art der daten in blob erkennen?
Blobs werden auch gern für komprimierten Daten genutzt (z.B. mit ZLib).
Dadurch spart man erheblich an der Größe der Datenbank. |
AW: wie art der daten in blob erkennen?
Unter Linux könntest du das BLOB auf der Festplatte zwischenspeichern und per "file" Kommando den Mime-Type herausbekommen:
Code:
Unter Windows gibt es ein paar Pendants zu "file", wobei
file --mime-type -b Downloads/logo.jpg
# image/jpeg ![]() |
AW: wie art der daten in blob erkennen?
FILE ist opensource ... könnte/kann man auch für Windows bereitstellen.
Da werden nicht nur diese MagicBytes (die ersten 1-4 Bytes) beachtet. Wenn es um Bilder geht, dann kann TPicture.LoadFromStream das inszwischen auch, für bei ihm registrierte Formate. Ganz früher hatte nur LoadFromFile auf die Dateiendung geachtet, aber seit 'ner Weile macht das LoadFromStream, über einige MagicBytes. (die Funktion kann man hoffentlich auch selber aufrufen, außer Emba ist mal wieder doof) |
AW: wie art der daten in blob erkennen?
Es gibt keine generelle Lösung dafür, schließlich müssen Blobs ja nicht notwendigerweise bekannten Dateiformate enthalten. Jeder Anwender und/oder Programmierer kann dort beliebige binäre Daten ablegen. Wenn Du sicher bist, dass es Dateien sind, helfen die bereits genannten Links wahrscheinlich weiter, aber Du solltest sicherstellen, dass dein Tool auch Zugriff auf generische Binärdaten erlaubt, z.B. wie bei einem Hex-Editor/Viewer. Genaugenommen ist das das sogar erste, was Du einbauen solltest.
|
AW: wie art der daten in blob erkennen?
Zitat:
Delphi-Quellcode:
Wobei es sich eher um ein Proof-of-Concept anstelle eines voll ausgereiften hoch optimierten quelltext handelt.
function GetBytesFormat(const AData: TBytes): Integer;
var signature: TBytes; begin Result := -1; signature := Copy(AData, 0, 8); if CompareMem(@signature[0], @[$FF, $D8, $FF, $DB], 4) then Result := 0 // JPEG else if CompareMem(@signature[0], @[$FF, $D8, $FF, $E0, $00, $10, $4A, $46], 8) then Result := 0 // JPEG else if CompareMem(@signature[0], @[$49, $46, $00, $01], 4) then Result := 0 // JPEG else if CompareMem(@signature[0], @[$FF, $D8, $FF, $EE], 4) then Result := 0 // JPEG else if CompareMem(@signature[0], @[$FF, $D8, $FF, $E1], 4) and CompareMem(@signature[6], @[$45, $78], 2) then Result := 0 // JPEG else if CompareMem(@signature[0], @[$69, $66, $00, $00], 4) then Result := 0 // JPEG else if CompareMem(@signature[0], @[$FF, $D8, $FF, $E0], 4) then Result := 0 // JPEG else if CompareMem(@signature[0], @[$89, $50, $4E, $47, $0D, $0A, $1A, $0A], 8) then Result := 1 // PNG else if CompareMem(@signature[0], @[$47, $49, $46, $38, $37, $61], 6) then Result := 2 // GIF87a else if CompareMem(@signature[0], @[$47, $49, $46, $38, $39, $61], 6) then Result := 2 // GIF89a else if CompareMem(@signature[0], @[$42, $4D], 2) then Result := 3 // BMP else if CompareMem(@signature[0], @[$00, $00, $01, $00], 4) then Result := 4 // ICO else if CompareMem(@signature[0], @[$49, $49, $2A, $00], 4) then Result := 5 // TIF else if CompareMem(@signature[0], @[$4D, $4D, $00, $2A], 4) then Result := 5 // TIFF ; end; |
AW: wie art der daten in blob erkennen?
Boar eh ... immer und immer wieder ... die sollem mal richtige Entwickler einstellen, die ihr eigenes Produckt selber benutzen.
Du kannst dich aber selber an jedes einzelne ImageFormat wenden und es fragen, ![]() also TBitmap.CanLoadFromStream, TPngImage.CanLoadFromStream, TJPEGImage.CanLoadFromStream usw. Ein GetFileFormats.FindFormat wäre natürlich einfacher, aber ..... mähhhhhhhhhh
Delphi-Quellcode:
unit Vcl.Graphics;
implementation <- was soll dieser perverse Scheiß immer? var ClipboardFormats: TClipboardFormats = nil; FileFormats: TFileFormatsList = nil; function GetFileFormats: TFileFormatsList; begin if FileFormats = nil then FileFormats := TFileFormatsList.Create; Result := FileFormats; end; function GetClipboardFormats: TClipboardFormats; begin if ClipboardFormats = nil then ClipboardFormats := TClipboardFormats.Create; Result := ClipboardFormats; end;
Delphi-Quellcode:
procedure TPicture.LoadFromFile(const Filename: string);
var Ext: string; GraphicClass: TGraphicClass; Context: TFindGraphicClassContext; begin Ext := ExtractFileExt(Filename).Remove(0, 1); GraphicClass := FileFormats.FindExt(Ext);
Delphi-Quellcode:
procedure TPicture.LoadFromStream(Stream: TStream);
var GraphicClass: TGraphicClass; Context: TFindGraphicClassContext; begin if Stream.Size - Stream.Position = 0 then GraphicClass := TBitmap else GraphicClass := FileFormats.FindFormat(Stream);
Delphi-Quellcode:
procedure TPicture.LoadFromClipboardFormat(AFormat: Word; AData: THandle;
APalette: HPALETTE); var GraphicClass: TGraphicClass; Context: TFindGraphicClassContext; begin GraphicClass := ClipboardFormats.FindFormat(AFormat); das was öffentlich ist, ist hierfür nicht nutzbar.
Delphi-Quellcode:
function GraphicFilter(GraphicClass: TGraphicClass): string;
var Filters: string; begin GetFileFormats.BuildFilterStrings(GraphicClass, Result, Filters); end; function GraphicExtension(GraphicClass: TGraphicClass): string; var I: Integer; begin for I := GetFileFormats.Count-1 downto 0 do if TFileFormatType(FileFormats[I]).GraphicClass.ClassName = GraphicClass.ClassName then begin Result := TFileFormatType(FileFormats[I]).Extension; Exit; end; Result := ''; end; function GraphicFileMask(GraphicClass: TGraphicClass): string; var Descriptions: string; begin GetFileFormats.BuildFilterStrings(GraphicClass, Descriptions, Result); end; |
AW: wie art der daten in blob erkennen?
Mein schnippsel sollte lediglich als Hilfestellung dienen wie man Signaturen erkennen könnte, er stammt aus etwas was keine Graphics oder Vcl kennt.
Das ich Graphikformate erkennen wollte ist in diesem Zusammenhang irrelevant. |
AW: wie art der daten in blob erkennen?
meinte nicht dich ... war auf die Entwickler bei Emba bezogen, weil die zwanghaft immer jeden Dreck verstecken müssen und sich regelrecht weigern etwas öffentlich zugänglich zu machen. :wall:
|
AW: wie art der daten in blob erkennen?
Zitat:
UNGETESTET: Zitat:
Delphi-Quellcode:
function GetBytesFormat(const AData: TBytes): Integer;
begin Result := -1; if Length(AData) < 8 then Exit; case AData[0] of $FF: if CompareMem(@AData[0], @[$FF, $D8, $FF], 3) then Result := 0; // JPEG $89: if CompareMem(@AData[0], @[$89, $50, $4E, $47, $0D, $0A, $1A, $0A], 8) then Result := 1; // PNG $47: if CompareMem(@AData[0], @[$47, $49, $46, $38], 4) then Result := 2; // GIF $42: if CompareMem(@AData[0], @[$42, $4D], 2) then Result := 3; // BMP $00: if CompareMem(@AData[0], @[$00, $00, $01, $00], 4) then Result := 4; // ICO $49, $4D: if CompareMem(@AData[0], @[$49, $49, $2A, $00], 4) or CompareMem(@AData[0], @[$4D, $4D, $00, $2A], 4) then Result := 5; // TIF/TIFF end; end; Zitat:
|
AW: wie art der daten in blob erkennen?
Zitat:
|
AW: wie art der daten in blob erkennen?
Zitat:
Delphi-Quellcode:
Lesbarer wird es jedenfalls, wenn man Daten und Code noch etwas trennt.
{$SCOPEDENUMS ON}
type TImageFormat = (Unknown, BMP, GIF87a, TIFF, JPEG, PNG, ICO); {$POINTERMATH ON} function GetBytesFormat(const AData: TBytes): TImageFormat; var Signature: LongWord; begin Result := TImageFormat.Unknown; if Length(AData) >= 2 then if PWord(AData)^ = $4D42 then Result := TImageFormat.BMP; if Length(AData) >= 4 then case PLongWord(AData)^ of $DBFFD8FF, $01004649, $EEFFD8FF, $00006669, $E0FFD8FF: Result := TImageFormat.JPEG; $E0FFD8FF: if (Length(AData) >= 8) and ((PLongWord(AData) + 1)^ = $464A1000) then Result := TImageFormat.JPEG; $E1FFD8FF: if (Length(AData) >= 6) and ((PWord(AData) + 2)^ = $7845) then Result := TImageFormat.JPEG; $474E5089: if (Length(AData) >= 8) and ((PLongWord(AData) + 1)^ = $0A1A0A0D) then Result := TImageFormat.PNG; $38464947: if Length(AData) >= 6 then case (PWord(AData) + 2)^ of $6137, $6139: Result := TImageFormat.GIF87a; end; $00010000: Result := TImageFormat.ICO; $002A4949, $2A004D4D: Result := TImageFormat.TIFF; end; end;
Code:
type
{$SCOPEDENUMS ON} TImageFormat = (Unknown, BMP, GIF87a, TIFF, JPEG, PNG, ICO); {$SCOPEDENUMS OFF} TImageSignature = array[-2..7] of Byte; const cImageSignatures: array[0..13] of TImageSignature = ( (Ord(TImageFormat.JPEG), 4, $FF, $D8, $FF, $DB, 0, 0, 0, 0), (Ord(TImageFormat.JPEG), 8, $FF, $D8, $FF, $E0, $00, $10, $4A, $46), (Ord(TImageFormat.JPEG), 4, $49, $46, $00, $01, 0, 0, 0, 0), (Ord(TImageFormat.JPEG), 4, $FF, $D8, $FF, $EE, 0, 0, 0, 0), (Ord(TImageFormat.JPEG), 6, $FF, $D8, $FF, $E1, $45, $78, 0, 0), (Ord(TImageFormat.JPEG), 4, $69, $66, $00, $00, 0, 0, 0, 0), (Ord(TImageFormat.JPEG), 4, $FF, $D8, $FF, $E0, 0, 0, 0, 0), (Ord(TImageFormat.PNG), 8, $89, $50, $4E, $47, $0D, $0A, $1A, $0A), (Ord(TImageFormat.GIF87a), 6, $47, $49, $46, $38, $37, $61, 0, 0), (Ord(TImageFormat.GIF87a), 6, $47, $49, $46, $38, $39, $61, 0, 0), (Ord(TImageFormat.BMP), 2, $42, $4D, 0, 0, 0, 0, 0, 0), (Ord(TImageFormat.ICO), 4, $00, $00, $01, $00, 0, 0, 0, 0), (Ord(TImageFormat.TIFF), 4, $49, $49, $2A, $00, 0, 0, 0, 0), (Ord(TImageFormat.TIFF), 4, $4D, $4D, $00, $2A, 0, 0, 0, 0) ); function GetBytesFormat(const Data: TBytes): TImageFormat; begin for var Signature: TImageSignature in cImageSignatures do if (Length(Data) >= Signature[-1]) and CompareMem(@Data[0], @Signature[0], Signature[-1]) then Exit(TImageFormat(Signature[-2])); Result := TImageFormat.Unknown; end;
Delphi-Quellcode:
{$SCOPEDENUMS ON}
type TImageFormat = (Unknown, BMP, GIF87a, TIFF, JPEG, PNG, ICO); {$SCOPEDENUMS OFF} var cImageSignatures: array of array of Byte = [ [Ord(TImageFormat.JPEG), $FF, $D8, $FF, $DB], [Ord(TImageFormat.JPEG), $FF, $D8, $FF, $E0, $00, $10, $4A, $46], [Ord(TImageFormat.JPEG), $49, $46, $00, $01], [Ord(TImageFormat.JPEG), $FF, $D8, $FF, $EE], [Ord(TImageFormat.JPEG), $FF, $D8, $FF, $E1, $45, $78], [Ord(TImageFormat.JPEG), $69, $66, $00, $00], [Ord(TImageFormat.JPEG), $FF, $D8, $FF, $E0], [Ord(TImageFormat.PNG), $89, $50, $4E, $47, $0D, $0A, $1A, $0A], [Ord(TImageFormat.GIF87a), $47, $49, $46, $38, $37, $61], [Ord(TImageFormat.GIF87a), $47, $49, $46, $38, $39, $61], [Ord(TImageFormat.BMP), $42, $4D], [Ord(TImageFormat.ICO), $00, $00, $01, $00], [Ord(TImageFormat.TIFF), $49, $49, $2A, $00], [Ord(TImageFormat.TIFF), $4D, $4D, $00, $2A] ]; function GetBytesFormat(const Data: TBytes): TImageFormat; begin for var Signature in cImageSignatures do if (Length(Data) >= Length(Signature)-1) and CompareMem(@Data[0], @Signature[1], Length(Signature)-1) then Exit(TImageFormat(Signature[0])); Result := TImageFormat.Unknown; end; |
AW: wie art der daten in blob erkennen?
Zitat:
@himitsu: Cooler Ansatz, das muss ich dringend mal testen wie das bei den verschieden langen Signaturen aufgefüllt mit Nullen klappt.
Delphi-Quellcode:
Das muss ich erstmal verdauen das da ein negativer Startindex steht.
TImageSignature = array[-2..7] of Byte;
Delphi-Quellcode:
und wie sowas funktionieren soll mit den Nullen die nicht zur Signatur gehören.
(Ord(TImageFormat.BMP), 2, $42, $4D, 0, 0, 0, 0, 0, 0),
Delphi-Quellcode:
if CompareMem(@signature[0], @[$FF, $D8, $FF, $E1], 4) and CompareMem(@signature[6], @[$45, $78], 2) then
Result := 0 // JPEG
Delphi-Quellcode:
hier kann ich schonmal sagen ist ein Fehler unterlaufen, der zweite Teil fängt bei Offset 6 an, wo da Nullen stehen.
(Ord(TImageFormat.JPEG), 6, $FF, $D8, $FF, $E1, $45, $78, 0, 0),
Danke auf jeden Fall für die Verschönerung meines PoC! |
AW: wie art der daten in blob erkennen?
Ja, damit die Signatur bei [0] beginnt :lol:
bei [-1] die eigentliche Länge (ohne die Nullen) und auf [-2] das Format (hab mir ersparrt das mit einem Record-Array zu bauen (
Delphi-Quellcode:
)
array of record Format: TImageFormat; Len: Integer; Signature: array[0..7] of Byte; end;
Vor allem, da Record-Konstanten sinnlos pervers hässlich sind. Aber ginge auch mit
Delphi-Quellcode:
, also [0] das Format, [1] die Länge und ab [2] die Signatur.
array[0..9]
Bei einem statischen Array ist die zweite Ebene immer gleich groß, darum mußte aufgefüllt werden, aber nachfolgend, mit dynamischen Arrays, geht es ohne Füllbytes. |
AW: wie art der daten in blob erkennen?
Zitat:
Offset 6 ... falsch gelesen. also eigentlich
Delphi-Quellcode:
(Ord(TImageFormat.JPEG), 8, $FF, $D8, $FF, $E1, 0, 0, $45, $78)
joar dann muß man das Ganze noch um eine Maske (AND) erweitern, um die zwischenliegenden FüllBytes "ignorieren" zu können
Delphi-Quellcode:
(Ord(TImageFormat.JPEG), {Len} 8, {Daten} $FF, $D8, $FF, $E1, 0, 0, $45, $78, {Maske} $FF, $FF, $FF, $FF, 0, 0, $FF, $FF)
oder um eine zweite Prüfung (CompareMem) mit zusätzlichem Offset+Len.
Delphi-Quellcode:
(Ord(TImageFormat.JPEG), {Len1} 4, {Offest2} 6, {Len2} 2, {Daten1} $FF, $D8, $FF, $E1, 0, 0, {Daten2} $45, $78) // für Daten an gleicher Stelle (0..3 und 6..7)
Delphi-Quellcode:
(Ord(TImageFormat.JPEG), {Len1} 4, {Offest2} 6, {Len2} 2, {Daten1} $FF, $D8, $FF, $E1, {Daten2} $45, $78, 0, 0) // oder für Daten hintereinander (4+2 von 8)
und die Anderen alle mit
Delphi-Quellcode:
, also Offest2=0 für "gibt's nicht"
{Offest2} 0, {Len2} 0,
Die Maske hätte den Vorteil auch Bits ignorieren zu können, bzw. mehr als nur einen Sprung machen zu können. |
AW: wie art der daten in blob erkennen?
Zitat:
Sorry, mir gings ja nur drum, dass ChatGPT durchaus interessante Lösungs-Gerüste aus dem bestehenden Code anbietet. Ich habe ihm nicht gesagt, dass er die ersten Zeichen in ein case packen soll, das finde ich durchaus einen bemerkenswerten Schritt. Persönlich wäre ich auch eher in die Richtung von himitsu, von einer Array-Konstante ausgegangen, um die Formate schön übersichtlich und lesbar zu kapseln. Wenn ich das dem Bot noch mitteile, dann macht der das sicher auch noch in einem nächsten Step. Leider "optimiert" der auch immer was weg, das stimmt, aber er kann interessante Lösungsansätze bieten und zum Beispiel Lösungen auch von anderen Programmiersprachen in Delphi übertragen und kombinieren. Das finde ich sehr interessant, auch wenn der Code meistens nicht direkt lauffähig ist. </OT> Am Ende des Tages ist die gewünschte Lösung doch immer noch eine rein persönliche Geschmackssache. Deswegen finde ich alle Lösungsansätze auch OK, solange sie ihren Dienst tun, auch wenn ich da meine eigenen Favoriten habe. |
AW: wie art der daten in blob erkennen?
Moin in die runde.
also erstemal fettes TKS fuer die rege beteiligung, aber da ich nicht weiss, welche art daten in den blobs sein werden (und ich somit auch keinen einfluss darauf habe, ob das format vllt. mitgespeichert wurde), habe ich mir ueberlegt, das jetzt erstmal anders zu loesen, denn der "user" wird selbst am besten wissen, welche daten er in welchen blobs ablegt. daher mache ich einfach eine "konfigurierbare speichern-unter-funktion", wo er selbst auswaehlen kann, in welchem format er die datei speichern - oder fuer eine eventuelle preview temp. speichern will. und vllt. kann man ja sogar dabei festlegen, mit welchem "viewer" man(n)/frau/sonstiges diese betrachten will. und sollte jemand doch noch ne bessere idee haben - immer her damit. wuensche ein gesegnetes wochenende... ...de Schorsch |
AW: wie art der daten in blob erkennen?
So ist's richtig: Betroffene zu Beteiligten machen :-D
|
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 12:48 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