Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TBitmap in record abspeichern


cscp - Di 23.01.07 22:03
Titel: TBitmap in record abspeichern
Hallo,
also ich habe ein Bitmap. Das möchte ich mit anderen Informationen abspeichern. Dazu habe ich folgendes Record definiert:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
type TScreenshot = record
  bmp: TBitmap;
  nme, date : String;
end;

var testVar : TScreenshot;


Wie kann ich nun mein schon vorhandenes Bitmap auf das testVar.bmp kopieren?
Wie ich einen Datensatz abspeicher das weiss ich bereits.
Danke im Vorraus!

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt


Narses - Di 23.01.07 23:47

Moin!

user profile iconcscp hat folgendes geschrieben:
Wie kann ich nun mein schon vorhandenes Bitmap auf das testVar.bmp kopieren?

Z.B. so: testVar.bmp.Assign(AnderesBitmap);

user profile iconcscp hat folgendes geschrieben:
Wie ich einen Datensatz abspeicher das weiss ich bereits.

Dir ist aber schon klar, dass du nicht mit z.B. typisierten Dateien arbeiten kannst, weil das record nur einen Zeiger auf das Bitmap enthält? :? ;)

cu
Narses


cscp - Do 25.01.07 07:52

nein das war mit nicht klar ^^

wie kann ich dass dann machen?

danke


jaenicke - Do 25.01.07 08:22

Nochmal als Erklärung, falls dir nicht klar ist, warum das nicht so geht: In dem Record wird lediglich ein Zeiger auf einen bestimmten Speicherbereich gespeichert (wie schon gesagt), der die Bitmap enthält. Nun ja, und wenn du den speicherst, dann speicherst du dessen 4 Byte, nicht aber den Inhalt der Bitmap.
Die einzige gespeicherte Information ist also, wo im Speicher sich die Bitmap befunden hat. ;-)
Das gilt auch für die Strings.<

Wie es geht?
Indem du dir eine eigene Prozedur schreibst, die das Speichern des Records in Einzelteilen übernimmt (und eine entsprechende Laderoutine).
Diese Prozedur speichert zunächst mit SaveToStream die Bitmap in einen MemoryStream. Dann nimmt sie einen FileStream und speichert zunächst eine Integer-Variable mit der Größe dieses MemoryStreams hinein, danach wird der Inhalt des MemoryStreams mit CopyFrom hineingeholt. (Nicht vergessen vorher die Position im MemoryStream auf 0 zu setzen!)
So, und jetzt nich die beiden Strings hinterherspeichern mit folgender Routine (die zum Laden ist auch gleich dabei):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
function LoadStringFromStream(Stream: TStream): String;
var
  Size: Integer;
begin
  try
    Stream.ReadBuffer(Size, SizeOf(Size));
    SetString(Result, nil, Size);
    Stream.Read(Pointer(Result)^, Size);
  except
    Result := '';
  end;
end;

procedure SaveStringToStream(S: String; Stream: TStream);
var
  Size: Integer;
begin
  Size := Length(S);
  Stream.WriteBuffer(Size, SizeOf(Size));
  Stream.WriteBuffer(Pointer(S)^, Size);
end;


Beim Laden muss das ganze umgekehrt gemacht werden.
Zu erst aus dem mit fmOpenRead geöffneten FileStream die Größe der gespeicherten Bitmap als Integer-Variable auslesen, dann soviele Bytes in einen MemoryStream kopieren, dessen Position auf 0 setzen und dann die Daten aus dem MemoryStream mit LoadFromStream in die Bitmap laden.
Nun noch die beiden Strings laden, fertig.