Entwickler-Ecke

Dateizugriff - Mehrere Bitmaps in eine Datei verpacken und direkt auslesen


Thomas233 - Mo 23.08.04 23:59
Titel: Mehrere Bitmaps in eine Datei verpacken und direkt auslesen
Hallo miteinander,

ich suche eine Möglichkeit mehrere Bitmaps in eine einzige Datei zu packen. Wichtig dabei wäre vor allem das ich beim Öffnen der Datei direkten Zugriff auf die Bitmaps (ohne sie vorher auf die Festplatte zu entpacken) kriege, sodass ich sie in einen Memory-Stream laden kann. :?:

Ich habe es bisher mit dem IStorage-Interface probiert (welches eher auf Klassenobjekte zugeschnitten ist) , mit typisierten Dateien (da schaffe ich einfach nicht die Bitmaps selbst abzuspeichern) und mit Streams.
Aber irgendwie gehen mir jetzt die Ideen aus, denn es klappt einfach nicht.
Vor allem die Speicherung der Bitmaps selbst (d.h. deren Pixel) macht mir immer wieder Probleme.

Ich wäre euch für einen Tipp sehr dankbar ! :P

Liebe Grüße,
Thomas


Keldorn - Di 24.08.04 08:28

Hallo

mit einer typisierten Datei wirst du das nie und nimmer hinbekommen, sobald du hier unterschiedliche Bildgröße hast ist schluß, außerdem bist du damit ziemlich unflexibel.

Nimm streams und nutze die bitmap.savetostream und loadfromstream-methoden. Speichere nacheinander die Bitmaps in den stream und ließ sie wieder aus. Bei Bitmaps sollte das gehen, bei jpgs gabs probleme, wenn ich mich recht erinnere. Wenn du beim auslesen Fehler erhälst, kontrollier die Position im Stream. Bei jpgs ging das nicht, beim auslesen eines Bildes war man dann immer gleich am ende des streams. Wenn das der Fall ist, mußt du noch die größe mit abspeicheren (evtl kleinen umweg über einen memorystream, um das rauszubekommen) und beim auslesen dann mit seek an die entsprechende Position springen.

Mit dem datailierten Speichern brauchst du dich nicht zu befassen, das macht alles die savetostream-methode für dich.

Mfg Frank


Delete - Di 24.08.04 12:55

Ich habe da mal eine kleine TArchive-Klasse geschrieben: http://www.luckie-online.de/Downloads/DelphiUnits/


Thomas233 - Di 24.08.04 13:07

Hi Michael,

ich habe mir deine Komponenten-Seite bereits angesehen. Leider hat mir sowohl deine Klasse für die typisierten Dateien nicht geholfen (weil ich es einfach nicht geschafft habe die einzelnen Pixel der Bitmaps abzuspeichern) als auch die Archiv-Klasse.

Der Haken ist nähmlich der, das ich die gepackten Dateien nicht entpacken will.
Ich will den direkten Zugriff auf jedes Bitmap in der gepackten Datei kriegen und es dann in einen Memory-Stream übertragen (eben ohne Umweg über die Festplatte).

Gibts dafür eine Lösung/Komponente ??

@Frank:
Mit Streams habe ich es auch bereits probiert, ging aber nicht.
Ich werde es trotzdem weiterhin damit versuchen !

Liebe Grüße,
Thomas


Keldorn - Di 24.08.04 13:16

Thomas233 hat folgendes geschrieben:

@Frank:
Mit Streams habe ich es auch bereits probiert, ging aber nicht.
Ich werde es trotzdem weiterhin damit versuchen !


Luckies Code habe ich mir nicht angeschaut, weiß nicht wie er es macht. aber wenn du hier schreibst "ging nicht" hilft das nicht weiter. poste deinen code, wie du es probiert hast, kamen Fehlermeldungen oder an was ist es gescheitert?
wie gesagt: mit typisierten Dateien machst du dir hier keine Freude.

Mfg Frank


Viper - Di 24.08.04 13:24

Hallo Thomas.

Hier mal ein kleines Beipsiel dafür, wie es mit einem FileStream und MemoryStream funktionieren könnte:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
//Speichern der Bitmaps in die Datei:
var
  Size: integer;
  FileStr: TFileStream;
  MemStr: TMemoryStream;
begin
  FileStr := TFileStream.Create('Hier der Datei-Pfad', fmCreate);
  MemStr := TMemoryStream.Create;
  try
    bmp1.SaveToStream(MemStr); //bmp1 ist irgendwo global als TBitmap deklariert
    Size := MemStr.Size;

    FileStr.Write(Size, SizeOf(integer) );
    FileStr.CopyFrom(MemStr, 0); //die 0 gibt an, dass der ganze MemoryStream kopiert werden soll

    MemStr.Clear;

    bmp2.SaveToStream(MemStr); //bmp2 ist irgendwo global als TBitmap deklariert
    Size := MemStr.Size;

    FileStr.Write(Size, SizeOf(integer) );
    FileStr.CopyFrom(MemStr);    
  finally
    MemStr.Free;
    FileStr.Free;
  end;
end;


//so, und nun laden:
var
  Size: integer;
  FileStr: TFileStream;
  MemStr: TMemoryStream;
begin
  FileStr := TFileStream.Create('Hier der Datei-Pfad', fmOpenRead);
  MemStr := TMemoryStream.Create;
  try
    FileStr.Read(Size, SizeOf(integer) );
    MemStr.CopyFrom(FileStr, Size);
    bmp1.LoadFromStream(MemStr);

    MemStr.Clear;

    FileStr.Read(Size, SizeOf(integer) );
    MemStr.CopyFrom(FileStr, Size);
    bmp2.LoadFromStream(MemStr);
  finally
    MemStr.Free;
    FileStr.Free;
  end;
end;

natürlich musst du diesen Code an dein Programm anpassen, da ich hier nur zwei Bitmaps in den Stream packe und wieder lade


Thomas233 - Di 24.08.04 13:47

Hi Viper,

ich hab den Fehler in meinem Code dank deiner Veranschaulichung endlich gefunden.

Und zwar habe ich bei dem Befehl "FileStream.CopyFrom" folgendes geschrieben:


Quelltext
1:
FileStream.CopyFrom(MemStream,MemStream.Size); //Tücken der Logik *g*                    


Dadurch bekam ich einen Stream-Lesefehler. Aber jetzt funktionierts endlich.

Vielen herzlichen Dank!

Liebe Grüße,
Thomas


zorxx - Do 26.08.04 17:21

Hallo,

eine Alternative wäre noch Ressourcen-Dateien und die in eine DLL verpacken.

Gruss

zorxx


Delete - Do 26.08.04 17:40

Du solltest dir auch nicht die Klasse für typisierte Dateien ankucken, sonder die TArchive Klasse. Die macht genau das, was du willst.


Thomas233 - Mi 01.09.04 20:41

Hi Luckie,

Luckie hat folgendes geschrieben:
Du solltest dir auch nicht die Klasse für typisierte Dateien ankucken, sonder die TArchive Klasse. Die macht genau das, was du willst.


Im einem frühreren Posting habe ich bereits folgendes geschrieben:
Zitat:

Der Haken ist nähmlich der, das ich die gepackten Dateien nicht entpacken will.
Ich will den direkten Zugriff auf jedes Bitmap in der gepackten Datei kriegen und es dann in einen Memory-Stream übertragen (eben ohne Umweg über die Festplatte).


Das stört mich nähmlich an der TArchiv-Komponente. Sonst würde ich sie ja nehmen ;-)

Liebe Grüße,
Thomas