Häufig benötigte Bitmaps sollen nur einmal gespeichert und zur Laufzeit geladen, geändert und mit Änderungen gespeichert werden.
Lösungsversuch mit Ressourcen: Mit Bitmaps.Res werden die Bitmaps nur einmal erstellt. Aber sie werden beim Kompilieren in jede EXE/DLL eingebunden; sie können zur Laufzeit u.U. bearbeitet werden; aber nicht mit Änderungen gespeichert werden.
Lösungsversuch mit ImageList: Laut Delphi-Hilfe werden alle Bitmaps einer ImageList intern in einer gemeinsamen Bitmap gespeichert.
Die gewünschten Ziele würden also erreicht, wenn ich diese gemeinsame Bitmap ,am Stück' einlesen, bearbeiten und speichern könnte - aber ausgerechnet die Methoden TImageList.ReadData und TImageList.WriteData sind private.
Versuch mit Nachbesserung von TImageList.WriteData<br>
Diese Funktion lässt sich einfach übernehmen; '||' habe ich als Ersatz für das Zeilenende benutzt.
procedure TForm1.Images_Write( ImageListe: TImageList; ImageFile: string ); ||
var SF: TFileStream; SA: TStreamAdapter; ||
begin ||
SF := TFileStream.Create(ImageFile); ||
SA := TStreamAdapter.Create(SF); ||
try ||
// der folgende Befehl ist wohl Windows-Standard und übernimmt ImageList.Handle ||
if not ImageList_Write(ImageListe.Handle, SA) ||
then raise EWriteError.CreateRes(@SImageWriteFail); ||
finally ||
SF.Free; ||
SA.Free; ||
end; ||
end;<br>
Wegen der folgenden Funktion weiß ich nicht, ob dies funktioniert; aber es sieht zumindest richtig aus und liefert keinen Laufzeitfehler.
Die Nachbesserung von TImageList.ReadData sollte ähnlich funktionieren (für Delphi 3 ff.):<br>
procedure TForm1.Images_Read( ImageListe: TImageList; ImageFile: string ); ||
var SF: TFileStream; SA: TStreamAdapter; ||
begin ||
SF := TFileStream.Create(ImageFile); ||
SA := TStreamAdapter.Create(Stream); ||
try ||
ImageListe.FreeHandle; ||
ImageListe.Handle := ImageList_Read(SA); ||
if ImageListe.Handle = 0 then raise EReadError.CreateRes(@SImageReadFail); ||
finally ||
SF.Free; ||
SA.Free; ||
end; ||
end;
Aber diese Variante funktioniert nicht: * Delphi weist bei ImageListe.OnCreate automatisch das benötigte Handle zu. * FreeHandle wird nicht umgesetzt. * ImageList_Read gibt einen ImageList-Handle zurück, der aber nicht direkt der schon vorhandenen ImageListe zugewiesen werden kann.<br>
Kann der Handle durch die Funktion zugewiesen werden mit var-Parameter für ImageListe? Gibt es einen anderen 'Umweg'?
Lösungsversuch mit einzelnen Bitmaps in einem gemeinsamem Stream/Datei: Wie bei AddImages wird jedes Bitmap der Liste an einen Stream (mit Speichern in einer Datei) angehängt bzw. ausgelesen. Es funktioniert prinzipiell wie gewünscht:
procedure TForm1.Images_Write( ImageListe: TImageList; ImageFile: string ); ||
var Bild: TBitmap; i1: integer; Ausgabe: TMemoryStream; ||
begin ||
Bild := TBitmap.Create; ||
Ausgabe := TMemoryStream.Create; ||
try ||
for i1 := 0 to ImageListe.Count - 1 ||
do begin ||
ImageListe.GetBitmap( i1, Bild ); ||
Bild.SaveToStream(Ausgabe); ||
end; ||
Ausgabe.SaveToFile( ImageFile ); ||
finally ||
Ausgabe.Free; ||
Bild.Free; ||
end; ||
end;
procedure TForm1.Images_Read ( ImageListe: TImageList; ImageFile: string ); ||
var Bild: TBitmap; Ausgabe: TMemoryStream; ||
begin ||
Bild := TBitmap.Create; ||
Ausgabe := TMemoryStream.Create; ||
ImageListe.Clear; ||
try ||
Ausgabe.LoadFromFile(ImageFile); ||
Ausgabe.Seek( 0, soFromBeginning ); ||
repeat ||
Bild.LoadFromStream(Ausgabe); ||
ImageListe.Add(Bild,nil); ||
until Ausgabe.Position >= Ausgabe.Size; ||
finally ||
Ausgabe.Free; ||
Bild.Free; ||
end; ||
end;
Aber unzumutbar ist: * Alle Bitmaps sehen 'unscharf' aus. * Bei weiteren Bitmaps sieht es so aus, als ob die anderen Bitmaps im Hintergrund stünden. Woran kann das liegen, und wie kann das vermieden werden? Danke für Tipps!
Lösungsversuch mit Ressourcen: Mit Bitmaps.Res werden die Bitmaps nur einmal erstellt. Aber sie werden beim Kompilieren in jede EXE/DLL eingebunden; sie können zur Laufzeit u.U. bearbeitet werden; aber nicht mit Änderungen gespeichert werden.
Lösungsversuch mit ImageList: Laut Delphi-Hilfe werden alle Bitmaps einer ImageList intern in einer gemeinsamen Bitmap gespeichert.
Die gewünschten Ziele würden also erreicht, wenn ich diese gemeinsame Bitmap ,am Stück' einlesen, bearbeiten und speichern könnte - aber ausgerechnet die Methoden TImageList.ReadData und TImageList.WriteData sind private.
Versuch mit Nachbesserung von TImageList.WriteData<br>
Diese Funktion lässt sich einfach übernehmen; '||' habe ich als Ersatz für das Zeilenende benutzt.
procedure TForm1.Images_Write( ImageListe: TImageList; ImageFile: string ); ||
var SF: TFileStream; SA: TStreamAdapter; ||
begin ||
SF := TFileStream.Create(ImageFile); ||
SA := TStreamAdapter.Create(SF); ||
try ||
// der folgende Befehl ist wohl Windows-Standard und übernimmt ImageList.Handle ||
if not ImageList_Write(ImageListe.Handle, SA) ||
then raise EWriteError.CreateRes(@SImageWriteFail); ||
finally ||
SF.Free; ||
SA.Free; ||
end; ||
end;<br>
Wegen der folgenden Funktion weiß ich nicht, ob dies funktioniert; aber es sieht zumindest richtig aus und liefert keinen Laufzeitfehler.
Die Nachbesserung von TImageList.ReadData sollte ähnlich funktionieren (für Delphi 3 ff.):<br>
procedure TForm1.Images_Read( ImageListe: TImageList; ImageFile: string ); ||
var SF: TFileStream; SA: TStreamAdapter; ||
begin ||
SF := TFileStream.Create(ImageFile); ||
SA := TStreamAdapter.Create(Stream); ||
try ||
ImageListe.FreeHandle; ||
ImageListe.Handle := ImageList_Read(SA); ||
if ImageListe.Handle = 0 then raise EReadError.CreateRes(@SImageReadFail); ||
finally ||
SF.Free; ||
SA.Free; ||
end; ||
end;
Aber diese Variante funktioniert nicht: * Delphi weist bei ImageListe.OnCreate automatisch das benötigte Handle zu. * FreeHandle wird nicht umgesetzt. * ImageList_Read gibt einen ImageList-Handle zurück, der aber nicht direkt der schon vorhandenen ImageListe zugewiesen werden kann.<br>
Kann der Handle durch die Funktion zugewiesen werden mit var-Parameter für ImageListe? Gibt es einen anderen 'Umweg'?
Lösungsversuch mit einzelnen Bitmaps in einem gemeinsamem Stream/Datei: Wie bei AddImages wird jedes Bitmap der Liste an einen Stream (mit Speichern in einer Datei) angehängt bzw. ausgelesen. Es funktioniert prinzipiell wie gewünscht:
procedure TForm1.Images_Write( ImageListe: TImageList; ImageFile: string ); ||
var Bild: TBitmap; i1: integer; Ausgabe: TMemoryStream; ||
begin ||
Bild := TBitmap.Create; ||
Ausgabe := TMemoryStream.Create; ||
try ||
for i1 := 0 to ImageListe.Count - 1 ||
do begin ||
ImageListe.GetBitmap( i1, Bild ); ||
Bild.SaveToStream(Ausgabe); ||
end; ||
Ausgabe.SaveToFile( ImageFile ); ||
finally ||
Ausgabe.Free; ||
Bild.Free; ||
end; ||
end;
procedure TForm1.Images_Read ( ImageListe: TImageList; ImageFile: string ); ||
var Bild: TBitmap; Ausgabe: TMemoryStream; ||
begin ||
Bild := TBitmap.Create; ||
Ausgabe := TMemoryStream.Create; ||
ImageListe.Clear; ||
try ||
Ausgabe.LoadFromFile(ImageFile); ||
Ausgabe.Seek( 0, soFromBeginning ); ||
repeat ||
Bild.LoadFromStream(Ausgabe); ||
ImageListe.Add(Bild,nil); ||
until Ausgabe.Position >= Ausgabe.Size; ||
finally ||
Ausgabe.Free; ||
Bild.Free; ||
end; ||
end;
Aber unzumutbar ist: * Alle Bitmaps sehen 'unscharf' aus. * Bei weiteren Bitmaps sieht es so aus, als ob die anderen Bitmaps im Hintergrund stünden. Woran kann das liegen, und wie kann das vermieden werden? Danke für Tipps!