Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Bilder aus einer externen Datei laden (https://www.delphipraxis.net/144156-bilder-aus-einer-externen-datei-laden.html)

Whatever 1. Dez 2009 13:14


Bilder aus einer externen Datei laden
 
Hallo!

Ich habe vor ein kleines Spiel zu schreiben in welchem ich circa 60 Bilddateien benötige. Ich möchte diese nicht unbedingt in einem Ordner im Spielverzeichnes liegen haben, sondern eben in einer externen Datei. Das Problem was sich hierbei stellt ist, dass ich damit noch keine Erfahrungen habe. Also habe ich ein wenig das Netz durchforstet und bin auf Themen wie z.B. Ressourcen-DLLs gestossen. Verwirrend waren allerdings Einträge über .res Dateien, die wohl den selben Zweck erfüllen. Meine Frage ist nun, was wohl für mein Problem am sinnvollsten ist.

Grüße

himitsu 1. Dez 2009 13:51

Re: Bilder aus einer externen Datei laden
 
du kannst:

die Dateien einfach in einen Stream packen und in 'ner Datei speichern

eine ZIP-Komponente verwenden und alles in einer ZIP verpacken

Resourcen (in der EXE oder einer DLL)

TImageList

...


Was für dich am Sinnfollsten ist, kannst du nur selber beantworten, da wir ja nicht alle deine Bedürfnisse kennen.

DeddyH 1. Dez 2009 14:03

Re: Bilder aus einer externen Datei laden
 
Eine *.res-Datei ist eine Datei, die Deine Ressourcen enthält. Diese kannst Du nun direkt in Deine Exe oder in eine DLL linken, welche Du dann mitliefern müsstest. Dazu musst Du nur im Quellcode Deiner Anwendung bzw. DLL die Zeile
Delphi-Quellcode:
{$R Datei.res} //"Datei" steht natürlich für den Dateinamen
einfügen, sofern die *.res im Projektordner liegt.

Whatever 1. Dez 2009 14:20

Re: Bilder aus einer externen Datei laden
 
Vielen Dank erstmal :thumb:
Ich habe mich jetzt für die DLL entschieden und auch gleich mit dem XN Resource Editor eine .res Datei erstellt und diese in eine DLL compiliert. Jetzt möchte ich gern eine dieser Grafiken aufrufen, was in einer Funktion geschehen soll, die ein TBitmap zurückgibt. Das einzige Problem was ich jetzt noch habe ist, dass die aufgerufene Ressource nicht gefunden wird. Ich vermute, dass ich die Grafik unter einem falschen "Pfad" versuche aufzurufen.

Delphi-Quellcode:
r := TResourceStream.Create(h,Datei,'Bitmap');
Grüße

DeddyH 1. Dez 2009 14:27

Re: Bilder aus einer externen Datei laden
 
Schau einmal hier: http://delphi.about.com/library/weekly/aa010405a.htm

himitsu 1. Dez 2009 14:32

Re: Bilder aus einer externen Datei laden
 
es kommt jetzt darauf an, wie du deine Resourcen-Datei erstellt und wie du die DLL eingebunden/geladen hast.

.CreateFromID mit DLL-Handle und ID-des-Bildes
.Create mit DLL-Handle und Name-des-Bildes

Whatever 1. Dez 2009 14:48

Re: Bilder aus einer externen Datei laden
 
Also hiermit möchte ich die Bilder aufrufen:

Delphi-Quellcode:
function GetCard(CardIndex:String):TBitmap;
  var
    h: Cardinal;
    r: TResourceStream;
    b: TBitmap;
  begin
    h:= LoadLibrary('CardsDLL.dll');
    if h <> 0 then
      begin
        r := TResourceStream.Create(h,CardIndex,'Bitmap');
        b := TBitmap.Create;
          try
            b.LoadFromStream(r);
            result:= b;
          finally
            b.Free;
            r.Free;
            FreeLibrary(h)
          end;
      end
    else
      RaiseLastOSError();
  end;
Von der Struktur her sieht meine DLL so aus:
Bitmap-1 -1.bmp
-2 -2.bmp
-3 -3.bmp
usw.
Falls das gemeint war :)

Hab mir das Tutorial mal angesehen, finde darin aber nicht unbedingt die Lösung für mein Problem... aber Danke trotzdem :)

himitsu 1. Dez 2009 15:04

Re: Bilder aus einer externen Datei laden
 
b.Free gibt übrigens dein Bitmap frei und der Wert in Result wäre somit ungültig/fehlerhaft

und bei einem fehler wärend der Restelltung des Bitmaps und des Resourcestreams, wäre die DLL nicht wieder entladen wurden.

und da du anscheinend Indize in der RES verwendest, würden sich diese auch beim Laden gut machen
Delphi-Quellcode:
function GetCard(CardIndex: Integer): TBitmap;
  var
    h: THandle;
    r: TResourceStream;
  begin
    h := LoadLibrary('CardsDLL.dll');
    if h <> 0 then
      try
        r := TResourceStream.CreateFromID(h, CardIndex, 'Bitmap');
        result := TBitmap.Create;
        try
          result.LoadFromStream(r);
        finally
          r.Free;
        end;
      finally
        FreeLibrary(h);
      end;
    else
      RaiseLastOSError;
  end;
Da Objekte als Result oftmals als genzwertig böse angesehn werden, könnte man es auch so machen
Delphi-Quellcode:
procedure GetCard(CardIndex: Integer; Var Bitmap: TBitmap);
  var
    h: THandle;
    r: TStream;
  begin
    h := LoadLibrary('CardsDLL.dll');
    if h <> 0 then
      try
        r := TResourceStream.CreateFromID(h, CardIndex, 'Bitmap');
        try
          if not Assigned(Bitmap) then
            Bitmap := TBitmap.Create;
          Bitmap.LoadFromStream(r);
        finally
          r.Free;
        end;
      finally
        FreeLibrary(h);
      end;
    else
      RaiseLastOSError;
  end;

Whatever 1. Dez 2009 15:24

Re: Bilder aus einer externen Datei laden
 
Macht Sinn! :-D
Dankeschön!
Ich bekomme allerdings beim Aufrufen eine Zugriffsverletzung....

Andreas L. 1. Dez 2009 15:43

Re: Bilder aus einer externen Datei laden
 
Hast du die res-Datei über ein Resourcenscript (.rc) erzeugt? Wenn ja, hast du einen Fehler in deiner Struktur:

Zitat:

Bitmap-1 -1.bmp
-2 -2.bmp
-3 -3.bmp
erste Name, dann Typ, dann Dateiname:

Code:
1 BITMAP 1.bmp
2 BITMAP 2.bmp
etc...
EDIT: Hab überlesen das du XN Resource Editor verwendest...

himitsu 1. Dez 2009 15:47

Re: Bilder aus einer externen Datei laden
 
hierbei sollte die Bitmap-Variable inizialisiert sein

entweder die übergebene Variable steht auf NIL oder sie enthält ein gültiges Bitmap.

Whatever 1. Dez 2009 16:10

Re: Bilder aus einer externen Datei laden
 
Hm....irgendwie versteh ichs nicht....

Andreas L. 1. Dez 2009 16:17

Re: Bilder aus einer externen Datei laden
 
Delphi-Quellcode:
var
  bmp: TBitMap;
begin
  bmp := TBitmap.Create;
  try
    //Bild mit dem Index 0 in bmp laden
    GetCard(0, bmp);
    //irgendwas mit bmp machen, z. B.
    Image1.Picture.Bitmap.Assign(bmp);
  finally
    bmp.Free;
  end;
end;

Whatever 1. Dez 2009 16:34

Re: Bilder aus einer externen Datei laden
 
Das interessante ist ja, dass es scheinbar nicht daran liegt :gruebel:

himitsu 1. Dez 2009 17:02

Re: Bilder aus einer externen Datei laden
 
Zitat:

Zitat von Andreas L.
Delphi-Quellcode:
var
  bmp: TBitMap;
begin
  bmp := TBitmap.Create;
  try
    //Bild mit dem Index 0 in bmp laden
    GetCard(0, bmp);
    //irgendwas mit bmp machen, z. B.
    Image1.Picture.Bitmap.Assign(bmp);
  finally
    bmp.Free;
  end;
end;

oder eben
Delphi-Quellcode:
var
  bmp: TBitMap;
begin
  bmp := nil;
  try
    //Bild mit dem Index 0 in bmp laden
    GetCard(0, bmp);
    //irgendwas mit bmp machen, z. B.
    Image1.Picture.Bitmap.Assign(bmp);
  finally
    bmp.Free;
  end;
end;
Zitat:

Zitat von Whatever
Das interessante ist ja, dass es scheinbar nicht daran liegt :gruebel:

Dann gibt es da etwas Pratisches, weches sich Debuggen nennt.

- man legen einen Haltepunkt (F5) an den Anfang dieser Prozedur
- starte sas Programm (F9)
- und geht dann mit F7 oder F8 schrittweise weiter
- und sage uns dann wo genau es knallt und kann gleichzeitig selber mal schauen was eventuell schief läuft

Whatever 1. Dez 2009 17:08

Re: Bilder aus einer externen Datei laden
 
Der Fehler sitzt in dieser Zeile:
Delphi-Quellcode:
r := TResourceStream.CreateFromID(h, CardIndex, 'Bitmap');
Nen BP musste ich dafür aber nicht setzen da die Exception einen sowieso immer an die jeweilige stelle wirft...
Das mit dem Initialisieren verhindert diese auch nicht.
:gruebel:

himitsu 1. Dez 2009 17:11

Re: Bilder aus einer externen Datei laden
 
Wie genau heißt denn die Exception?

So wie es aussieht, wird wohl die Resource nicht gefunden. :gruebel:

Whatever 1. Dez 2009 17:19

Re: Bilder aus einer externen Datei laden
 
Eine Zugriffsverletzung. Also die DLL wird auf jeden Fall gefunden, aber die Ressource in ihr wohl nicht, was sich an der Adresse, die nicht gelesen werden kann sehen lässt.(00000002 für Ressource 2; 00000003 für Ressource 3; usw.)
Aber warum werden diese nicht gefunden.... Ich habe mir meine DLL nochmal mit einem Programm angesehen und.... naja die Ressourcen liegen an ihren Plätzen...
:gruebel:

himitsu 1. Dez 2009 18:08

Re: Bilder aus einer externen Datei laden
 
schau einfach mal, was alles in der DLL drin ist
Delphi-Quellcode:
uses Types;

function EnumResTypeProc(hModule: THandle; lpszType: PChar; lParam: Integer): LongBool; StdCall;
var
  arr: ^TStringDynArray absolute lParam;
begin
  SetLength(arr^, Length(arr^) + 1);
  if Cardinal(lpszType) > $FFFF then arr^[High(arr^)] := lpszType
  else arr^[High(arr^)] := Format('#%d', [Integer(lpszType)]);
  Result := True;
end;

function EnumResNameProc(hModule: THandle; lpszType, lpszName: PChar; lParam: Integer): LongBool; StdCall;
begin
  TMemo(lParam).Lines.Add(lpszType + ' ' + lpszName);
  Result := True;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  h: THandle;
  i: Integer;
  ResTypes: TStringDynArray;
begin
  h := HInstance; // hier dein DLL-Handle setzen
  EnumResourceTypes(h, @EnumResTypeProc, Integer(@ResTypes));
  for i := 0 to High(ResTypes) do
    EnumResourceNames(h, PChar(ResTypes[i]), @EnumResNameProc, Integer(Memo1));
end;
Memo1 = TMemo

Whatever 1. Dez 2009 18:36

Re: Bilder aus einer externen Datei laden
 
Wow vielen Dank!! :shock:
Zitat:

#10 DVCLAL
#10 PACKAGEINFO
Das ist in der DLL...Aber...Wo sind meine Bilder

Whatever 2. Dez 2009 17:02

Re: Bilder aus einer externen Datei laden
 
Hm.... Hat zufällig jemand eine Idee warum ich nicht an meine Ressourcen komme? :gruebel:

*Push* :)

himitsu 2. Dez 2009 17:10

Re: Bilder aus einer externen Datei laden
 
Kannst du mal die DLL hochladen?

Whatever 2. Dez 2009 17:13

Re: Bilder aus einer externen Datei laden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Jup das ist sie...

himitsu 2. Dez 2009 17:31

Re: Bilder aus einer externen Datei laden
 
blöd daß die Exceptions einfach unterschlagen werden :wall:
#2 = Bitmap
#10 = RCData

die Bilder sind also doch da :-D

Delphi-Quellcode:
function EnumResTypeProc(hModule: THandle; lpszType: PChar; lParam: Integer): LongBool; StdCall;
var
  arr: ^TStringDynArray absolute lParam;
begin
  SetLength(arr^, Length(arr^) + 1);
  if Cardinal(lpszType) > $FFFF then arr^[High(arr^)] := lpszType
  else arr^[High(arr^)] := Format('#%d', [Integer(lpszType)]);
  Result := True;
end;

function EnumResNameProc(hModule: THandle; lpszType, lpszName: PChar; lParam: Integer): LongBool; StdCall;
begin
  if Cardinal(lpszName) > $FFFF then TMemo(lParam).Lines.Add(lpszType + ' ' + lpszName)
  else TMemo(lParam).Lines.Add(lpszType + ' ' + Format('#%d', [Integer(lpszName)]));
  Result := True;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  h: THandle;
  i: Integer;
  ResTypes: TStringDynArray;
begin
  h := LoadLibrary('C:\Dokumente und Einstellungen\Administrator\Desktop\CardsDLL.dll');
  EnumResourceTypes(h, @EnumResTypeProc, Integer(@ResTypes));
  for i := 0 to High(ResTypes) do
    EnumResourceNames(h, PChar(ResTypes[i]), @EnumResNameProc, Integer(Memo1));
end;
jetzt mal gucken warum der nicht läd

nutze mal RT_BITMAP statt 'Bitmap'

[edit]
so geht's :)
Delphi-Quellcode:
r := TResourceStream.CreateFromID(h, CardIndex, RT_BITMAP);

Whatever 2. Dez 2009 21:48

Re: Bilder aus einer externen Datei laden
 
Aaaaah vielen Dank! Jetzt wird das Bild gefunden... allerdings kommt gleich die nächste Exception hinterher, die sagt, dass die Bitmap ungültig ist :gruebel:

Whatever 4. Dez 2009 15:22

Re: Bilder aus einer externen Datei laden
 
Hallo,

leider muss ich nochmal pushen, da mir einfach nicht klar ist warum die geladene Bitmap ungültig sein soll. Die Exception tritt beim Anzeigen des Bildes auf:
Delphi-Quellcode:
Image1.Picture.Bitmap.Assign(bmp);
Vielleicht hat ja jemand eine idee...

DeddyH 4. Dez 2009 16:43

Re: Bilder aus einer externen Datei laden
 
Wie wäre es denn mal mit mehr Quellcode?

Andreas L. 4. Dez 2009 18:23

Re: Bilder aus einer externen Datei laden
 
Die Bilder die du in der ressource abgelegt hast sind auch ganz sicher vom Typ Bitmap? Nicht Jpeg oder so?

Whatever 4. Dez 2009 18:27

Re: Bilder aus einer externen Datei laden
 
Ich würde gerne mehr Code zeigen allerdings besteht dieses Projekt bis jetzt nur aus dieser Funktion :-D
Es sind ganz sicher Bitmaps... zählen bei diesen noch andere Faktoren/Eigenschaften der Bitmap an denen es liegen könnte?
Vielen Dank übrigens :wink:

Whatever 4. Dez 2009 18:40

Re: Bilder aus einer externen Datei laden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Könnte es sein, dass ich versuche den "Ordner" in der DLL zu laden. Ich habe einen Screenshot angehängt, in dem man die Struktur der DLL sieht. Das Markierte sieht ja schwer nach Pfad aus und demnach... naja lade ich den Ordner als Bitmap. Ich hab keine Ahnung ob da was dran ist, ich arbeite zu ersten mal mit Dlls :wink:

Andreas L. 4. Dez 2009 19:59

Re: Bilder aus einer externen Datei laden
 
Hast du schon Imagw1.Picture.Bitmap.LoadFromResourceID(); bzw LoadFromResoruceName versucht?

Whatever 4. Dez 2009 20:12

Re: Bilder aus einer externen Datei laden
 
Jetzt ist die Verwirrung komplett! :-D
Vielen vielen Dank es funktioniert.... :thumb: :thumb: :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:28 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