AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken wie art der daten in blob erkennen?
Thema durchsuchen
Ansicht
Themen-Optionen

wie art der daten in blob erkennen?

Ein Thema von schorsch666 · begonnen am 30. Aug 2023 · letzter Beitrag vom 3. Sep 2023
Antwort Antwort
Seite 3 von 3     123   
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#21

AW: wie art der daten in blob erkennen?

  Alt 1. Sep 2023, 13:00
@himitsu, ich kam mit Deiner Art leider nicht ganz zurecht aber habe es recht gut optimiert finde ich
Delphi-Quellcode:
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.
@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.
Gruß vom KodeZwerg

Geändert von KodeZwerg ( 1. Sep 2023 um 13:08 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#22

AW: wie art der daten in blob erkennen?

  Alt 1. Sep 2023, 15:56
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 Delphi-Referenz durchsuchenTRect.Create anstatt einer externen Funktion ala Delphi-Referenz durchsuchenRect, bzw. Delphi-Referenz durchsuchenTPoint.Create und Delphi-Referenz durchsuchenPoint.
Schön wäre bestimmt es, wenn Emba hier den Constructor implitit für Casts benutzen würde, also TSignature(...) alternativ zu TSignature.Create(...) .

Delphi-Quellcode:
  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;
Ja, der Code wird so weniger optimal, aber vom Code her wird es teilweise schöner.
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 + .
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 1. Sep 2023 um 16:01 Uhr)
  Mit Zitat antworten Zitat
schorsch666

Registriert seit: 21. Apr 2011
81 Beiträge
 
#23

AW: wie art der daten in blob erkennen?

  Alt 3. Sep 2023, 11:30
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

Geändert von schorsch666 ( 3. Sep 2023 um 11:43 Uhr)
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
701 Beiträge
 
Delphi 12 Athens
 
#24

AW: wie art der daten in blob erkennen?

  Alt 3. Sep 2023, 13:24
P.S.: hat jemand ne idee, wie ich .pdfs/word/excel - zumindest aber .pdf's anzeigen koennte?
Die einfachste Methode ist es, die Daten aus dem BLOB in eine Datei mit der korrekten Extension zu schreiben und diese dann per ShellExecute(Ex) durch Windows in der zugeordneten Anwendung öffnen zu lassen.

Wenn die so erzeugten Dateien nicht auf der Platte bleiben sollen, nachdem der Benutzer sie sich angesehen hat, kann man die Datei per API CreateFile öffnen bevor man sie an ShellExecute übergibt. Dabei spezifiziert man FILE_FLAG_DELETE_ON_CLOSE und FILE_ATTRIBUTE_TEMPORARY in den Flags und hält die Datei offen, bis das Programm beendet wird. Windows löscht die Datei dann automatisch wenn das letzte Filehandle gesschlossen wird.
Peter Below
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


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 19:38 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