AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Funktion: Graphic anhand des Namens aus Res erstellen
Thema durchsuchen
Ansicht
Themen-Optionen

Funktion: Graphic anhand des Namens aus Res erstellen

Ein Thema von whiteF · begonnen am 16. Feb 2016 · letzter Beitrag vom 17. Feb 2016
Antwort Antwort
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
989 Beiträge
 
Delphi 6 Professional
 
#1

AW: Funktion: Graphic anhand des Namens aus Res erstellen

  Alt 17. Feb 2016, 04:55
Hmm...

Bei Bildern verwende ich eine andere Herangehensweise, gerade, wenn der Dateiname/Dateiende nicht vorhanden ist:

Ich werte die 'Magic Bytes' des FileStreams aus.
Somit kann ich auch zwischen verschiedenen Bildformaten unterscheiden ohne deren Namen zu erkennen.

Funktioniert auch mit ResourceStreams

Mal kurz aus einer meiner Units heraus kopiert:

Delphi-Quellcode:

const
  C_Magic_BM : array[0..1] of Byte = (Ord('B'),Ord('M'));
  C_Magic_BMP : array[0..2] of Byte = (Ord('B'),Ord('M'),Ord('P'));
  C_Magic_XBM : array[0..6] of Byte = (Ord('#'),Ord('d'),Ord('e'),Ord('f'),Ord('i'),Ord('n'),Ord('e'));
  C_Magic_JPG : array[0..1] of Byte = ($FF,$D8);
  C_Magic_GIF : array[0..2] of Byte = (Ord('G'),Ord('I'),Ord('F'));
  C_Magic_WMF : array[0..3] of Byte = ($D7,$CD,$C6,$9A);
  C_Magic_PNG : array[0..7] of Byte = (137,80,78,71,13,10,26,10);
  C_Magic_JPF : array[0..3] of Byte = ($00,$00,$00,$0C);
  C_Magic_JP2 : array[0..7] of Byte = ($00,$00,$00,$0C,$6A,$50,$20,$20);
  C_Magic_JPK : array[0..3] of Byte = ($FF,$4F,$FF,$51);

  C_Magic_TIF1 : array[0..3] of Byte = ($49,$49,$2A,$00);
  C_Magic_TIF2 : array[0..3] of Byte = ($4D,$4D,$00,$2A);


function CheckMagicNo(AFileData : array of Byte; aMagicBytes : array of Byte):boolean;
var
  i : integer;
begin
  result := length(AFileData) >= length(aMagicBytes);
  if result then begin
    for i := 0 to length(aMagicBytes) -1 do begin
      if AFileData[i] <> aMagicBytes[i] then begin
        result := false;
        break;
      end;
    end;
  end;
end;

function IsPicture(const AFileName : WideString):boolean;
var
  ByteArr : array[0..7] of Byte;
  tmpStream : TFileStream;
begin
  result := true;
  try
    if IsWebPFile2(AFileName) then exit; // TWEBPImage

    tmpStream := TFileStream.Create(AFileName,fmOpenRead);
    try
      tmpStream.Position := 0;
      if tmpStream.Read(ByteArr,8) = 8 then begin
        if CheckMagicNo(ByteArr,C_Magic_BM) then exit; // TBitmap
        if CheckMagicNo(ByteArr,C_Magic_BMP) then exit; // TBitmap
        if CheckMagicNo(ByteArr,C_Magic_XBM) then exit; // TXBMImage
        if CheckMagicNo(ByteArr,C_Magic_JPG) then exit; // TJPEGImage
        if CheckMagicNo(ByteArr,C_Magic_GIF) then exit; // TGIFImage
        if CheckMagicNo(ByteArr,C_Magic_WMF) then exit; // WMF
        if CheckMagicNo(ByteArr,C_Magic_PNG) then exit; // TPNGObject
        if CheckMagicNo(ByteArr,C_Magic_JPF) then exit; // JPF
        if CheckMagicNo(ByteArr,C_Magic_JP2) then exit; // JP2 JPEG2000
        if CheckMagicNo(ByteArr,C_Magic_JPK) then exit; // J2K
        if CheckMagicNo(ByteArr,C_Magic_TIF1) then exit; // Tif little endian format
        if CheckMagicNo(ByteArr,C_Magic_TIF2) then exit; // Tif big endian format

        tmpStream.Position := 0;
        if TargaCanLoad(tmpStream) then exit; // TTarga;
      end;
      result := false; // Kein lesbares Image oder keine 8 bytes
    finally
      tmpStream.Free;
    end;
  except
    result := false;
    // Datei nicht zu öffnen, also ignorieren
  end;
end;
Statt des Exits kannst Du dann einfach das TGrafic-Objekt mit dem geladenen Bild zurück geben und anstelle des FileStreams/FileName nimmst Du den ResourceStream.

Somit ist es egal, wie das Bild in der Resource deklariert ist, es kann dort alles als BinStream abgelegt werden.
  Mit Zitat antworten Zitat
whiteF

Registriert seit: 14. Okt 2008
45 Beiträge
 
#2

AW: Funktion: Graphic anhand des Namens aus Res erstellen

  Alt 17. Feb 2016, 08:25
Danke für die beiträge,
Ich werde sie heute abend mal testen.

@HolgerX
Danke für den hinweis mit den magic bytes. Aber die jeweiligen streams müsste man nach dem check doch erstmal dem entsprechenden bild (TBitmap, TPNGImage, TGIFImage, TJPEGImage) zuweisen bevor man diese dem TGraphic object übergibt.

Ich werde diese variante mit der funktion von Uwe kombinieren und mal schauen ob da wa pasenses rauskommt.

Die Lösung von Sir Rufo ist ja sehr ambitioniert. Ich hoffe nicht das du wg mir soviel aufwand betrieben hast
Für 2-4 kleine bilder innerhalb der anwendung reicht glaub ich so eine kleine funktion. Für mehr scheint mir deine lösung sehr vereinfachend zu sein.

Viele Grüße
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Funktion: Graphic anhand des Namens aus Res erstellen

  Alt 17. Feb 2016, 10:19
Die Lösung von Sir Rufo ist ja sehr ambitioniert. Ich hoffe nicht das du wg mir soviel aufwand betrieben hast
Für 2-4 kleine bilder innerhalb der anwendung reicht glaub ich so eine kleine funktion. Für mehr scheint mir deine lösung sehr vereinfachend zu sein.
Wenn du dir die Lösung genau anschaust, dann sieht man eigentlich keinen wirklichen Aufwand. Ein paar kleine Klassen, die als Ressourcen-Stellvertreter einem die eigentliche Arbeit abnehmen.

Der meiste Teil des Source entstand durch Code-Completion ...

Mir ist es egal, ob das Projekt groß oder klein ist. Wichtig ist mir immer den Boilerplate-Code wegzubekommen, sonst sieht man die wirkliche Funktion vor lauter Code nicht mehr.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
989 Beiträge
 
Delphi 6 Professional
 
#4

AW: Funktion: Graphic anhand des Namens aus Res erstellen

  Alt 17. Feb 2016, 14:58
Danke für die beiträge,
@HolgerX
Danke für den hinweis mit den magic bytes. Aber die jeweiligen streams müsste man nach dem check doch erstmal dem entsprechenden bild (TBitmap, TPNGImage, TGIFImage, TJPEGImage) zuweisen bevor man diese dem TGraphic object übergibt.

Ich werde diese variante mit der funktion von Uwe kombinieren und mal schauen ob da wa pasenses rauskommt.
Brauchst nur dort wo z.B.:
  if CheckMagicNo(ByteArr,C_Magic_BM) then exit; steht ein

if not Assigned(result) and CheckMagicNo(ByteArr,C_Magic_BM) then result := TBitmap.Create; und unten dann ein

if Assigned(result) then result.LoadFromStream(RS); (Freihand zusammen geschrieben/kopiert )
  Mit Zitat antworten Zitat
Antwort Antwort

 

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 03:51 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