![]() |
Bitmap speichern mit File of MyRecord
hi,
versuche ein Bitmap zu speichern, nur leider funktioniert das irgend wie nicht. Hier mal mein Code
Delphi-Quellcode:
Hat jemand eine idee?
Type
rNetDevice = record Typ, PositionX, PositionY : integer; Bitmap : TBitmap; end; ... Procedure Save; var Datei : File of rNetDevice; Datensatz : rNetDevice; begin AssignFile(Datei,fName); Reset(Datei); Seek(Datei, 0); // zum Dateianfang for i:=0 to fObjList.Count-1 do begin device := TNetDevice(fObjList.Objects[i]); Datensatz.Typ := 0; Datensatz.PositionX := device.Position.x; Datensatz.PositionY := device.Position.y; Datensatz.Bitmap := TBitmap.Create; Datensatz.Bitmap.Width := device.Bitmap.Width; Datensatz.Bitmap.Height := device.Bitmap.Height; Datensatz.Bitmap.canvas.Draw(0,0,device.Bitmap); Write(Datei, Datensatz); end; CloseFile(Datei); end; |
Re: Bitmap speichern mit File of MyRecord
Ja: dein Record hat keine Feste Länge (wenn man das Bitmap einbezieht) bzw. es wird nur ein Zeiger auf das Bitmap gespeichert, der nachher nicht mehr gültig ist.
Lösung: eine ordentliche Dateistruktur verwenden: Wenn du viele Klassen hast, empfehle ich dir die ![]() |
Re: Bitmap speichern mit File of MyRecord
Dein Bitmap was du versuchst zu speichern ist im eigentlichem Sinn sur ein Zeiger auf einen
bestimten Punkt im Speicher. Wenn du nun dein Bitmap in die Datei schreiben möchtest busst du wohl oder übel die realen RGB-Daten deines Bitmaps speichern. Baue dir dazu ein Array, lies die RGB-Daten über Scanline ein und speicher dann das Array. Die Grösse des must du nun auch speichern. Du kannst natürlich auch einen anderen Weg nutzen, TBitmap unterstützt das speichen in Streams. Das ist etwas eleganter und einfacher. Das sähe in etwa so aus:
Delphi-Quellcode:
procedure ...
var nd: rNetDevice; Temp: TMemoryStream; i: integer; B: Byte; begin nd.Typ := 1; nd.PositionX := 2; nd.PositionY := 3; Temp := TMemoryStream.Create; Image1.Picture.Bitmap.SaveToStream(Temp); nd.BitmapLength := Temp.Size; SetLength(nd.Bitmap, nd.BitmapLength + 1); Temp.Position := 0; for i := 0 to nd.BitmapLength -1 do begin Temp.Read(B, 1); nd.Bitmap[i] := B; end; Temp.Free; end; |
Re: Bitmap speichern mit File of MyRecord
Zitat:
|
Re: Bitmap speichern mit File of MyRecord
Asso, ja...
Delphi-Quellcode:
Type
rNetDevice = record Typ, PositionX, PositionY : integer; Bitmap : Array of Byte; BitmapLength; Cardinal; end; |
Re: Bitmap speichern mit File of MyRecord
thx
|
Re: Bitmap speichern mit File of MyRecord
habe es jetzt so gemacht wie oben
speichern
Delphi-Quellcode:
das laden
var
i,m : integer; file_device_info : File of TNetDeviceInfo; s : TMemoryStream; b : byte; begin AssignFile(file_device_info,'test.dat'); for i:=0 to NetStruktur.Devices.Count-1 do begin s := TMemoryStream.Create; device_info := pNetDeviceInfo(NetStruktur.Devices.Objects[i]); device_info.fDesigner.fBitmap.SaveToStream(s); for m:=0 to device_info.fDesigner.fBitmapLength -1 do begin s.Read(b,1); device_info.fDesigner.fBitmapArray[m] := b; end; Write(file_device_info,device_info); s.free; end; CloseFile(file_device_info); end;
Delphi-Quellcode:
nur wenn ich das bild speicher ist das bild leer.
var
file_device_info : File of TNetDeviceInfo; b : Byte; m : TMemoryStream; begin AssignFile(file_device_info,'test.dat'); Reset(file_device_info); while not eof(file_device_info) do begin device_info := NetStruktur.CreateNewDevice; m := TMemoryStream.Create; Read(file_device_info,device_info); for i:=0 to device_info.fDesigner.fBitmapLength - 1 do begin b := device_info.fDesigner.fBitmapArray[i]; m.Write(b,1); end; device_info.fDesigner.fBitmap.LoadFromStream(m); m.Free; end; CloseFile(file_device_info); end; Aber in fBitmapArray stehen zahlen Habe ich was falsch gemacht? |
Re: Bitmap speichern mit File of MyRecord
na super habe nur
m.Position :=0; vergessen :wall: |
Re: Bitmap speichern mit File of MyRecord
Also mich wundert da gerade etwas. Ein dynamisches Array ist doch eigentlich auch nichts anderes als ein Pointer. Somit hast du lediglich den Pointer des Bitmaps gegen einen Anderen ausgetauscht. Und eigentlich müssen die Records auch immer die gleiche Größe haben wenn ich mich recht entsinne. Und wenn du variable Speicherbereiche (Bitmaps) hast lässt sich so etwas nur schwer realisieren.
Ich würde dir da besser empfehlen, dass du es eher folgendermaßen erledigst. Lass das File of und benutzt die Klasse TStream. Für Dateien dann die Ableitung TFileStream. Zu mal du dann auch das Bitmap direkt laden kannst. Bzw könnte der Stream dann auch woanders herkommen. Zum Beispiel Indy, Memorystream etc.
Delphi-Quellcode:
Das Bitmap hängt nur im Record, da es mit dazu gehört. Es soll aber nicht in die Datei geschrieben oder aus ihr gelesen werden. Evtl. würde ich da überlegen das TNetDeviceInfo noch mal zu kappseln und das record jetzt als Header zu sehen. Sonst kann es schnell mal passieren, dass du den Pointer des Bitmaps doch mal mit schreibst. Ist nur für die Sicherheit.
Type
TNetDeviceInfo = packed record Typ, PositionX, PositionY : integer; BitmapLength: Cardinal; Bitmap: TBitmap; end; procedure TForm1.FormCreate(Sender: TObject); var ND: TNetDeviceInfo; FS: TFileStream; begin FS := TFileStream.Create('test.dat', fmOpenRead); try // Hier wichtig. Beschreibung siehe unten. FS.Read(ND, SizeOf(ND) - SizeOf(TBitmap)); ND.Bitmap := TBitmap.Create; ND.Bitmap.LoadFromStream(FS); finally FS.Free; end; end; Beim Schreiben solltest du das Bitmap aber trotzdem noch in einen MemoryStream packen, da du die Größe wahrscheinlich benötigen wirst. Ansonsten weißt du nicht an welche Stelle du hingehen müsstest um das nächste Record zu lesen ohne, dass du das Bitmap komplett einlesen lässt. So kannst du es einfach überspringen. Bei Records die mit Dateien oder Speicherblöcken zu tun haben solltest du immer packed benutzen. Das sorgt dafür, dass Delphi das Record nicht automatisch erweitert. Sonst kann es passieren, dass du nicht benutzten Speicher in der Datei hast der so nicht beabsichtig ist. Wenn sich dann jemand anderes ausversehen genau an die Spezifikation hält geht es nicht mehr. |
Re: Bitmap speichern mit File of MyRecord
Zitat:
2. Speichert er die Bilddaten direkt byteweise aus dem MemoryStream, in dem das Bitmap gespeichert wurde (SaveToStream) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:21 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