Hallo zusammen,
Ich hab mir eine kleine Komponente entwickelt, auf der mit Andorra2D mehrere Bilder gerendert werden.
Diese lade ich zuvor von "thetvdb.com" (Größe: 680x1000px als JPG) und speicher sie lokal in einer Cache-Datei.
Der ganze Weg bis dahin (suchen, download+speichern) ist relativ fix und stört das Programm in keinster Weise.
Ursprünglich wollte ich eigentlich eine
VCL Komponente bauen, da das Ding aber schon bei 10 Bildern (die ich (einmalig) mit GR32 runterskaliert habe) in die Knie. Und da ich auch ein paar schöne Visuelle Effekte hinzufügen wollte bin ich auf Andorra umgestiegen.
Erster Versuch war mit der Andorra Sprite-Engine, war mir zu langsam war (zusätzlich hatte ich ein paar Probleme den Bild-lade-Vorgang (Thread) zu Synchronisieren.
Jetzt hab ich nur eine AdImageList in die ich die (25 Bilder) lade und diese dann mit AdImage.DrawAlpha ausgebe. Soweit ja ganz schön und toll. Nur schießt der Speicherverbrauch über 100 MB hinaus und das gefällt mir nicht ganz.
Mein erster Gedanke war, ob es eventuell möglich ist die Bilder in der AdImageList auf eine definierte Größe zu verkleinern und sobald eine größere Zoomstufe gewählt wird diese neu zu laden und erneut verkleinern.
Geil wären natürlich (Andorra) Hausmittel, da der Weg z.B. über GR32 wieder Zeit kostet.
Daniel
Falls jemand Vorschläge für die
VCL Lösung hat, hier ein paar Angaben dazu:
Der Ursprüngliche Weg (
VCL Komponente) steht natürlich auch noch zur Wahl, sofern mir jemand bei diesen Problemen helfen kann:
- "Flackern" bei Resize / Zoom / Scrollen
- Bei anderen Komponenten zeichne ich bisher immer im WM_Paint Event, mit der BitBlt Funktion
- Zusätzlich zeichnet meine Paint Funktion NUR den sichtbaren Bereich der Komponente
- Auch hier war das Problem mit dem hohen Speicherverbrauch für die Bilder und zusätzlich dass das Zeichnen recht langsam war
hier mal der Ausschnitt meiner "alten"
VCL Zeichenfunktion
Delphi-Quellcode:
// wall => TBitmap32 (bei Komponenten Erstellung instanziert, im Resize werden Width+Height auf Komponenten Eigenschaften gesetzt)
//wall wird im Paint ereignis via BitBlt auf den Canvas der Komponente kopiert
//( der weg ist nur weil ich in der DrawItem Funktion schneller auf Bitmap32 als auf Bitmap zeichnen kann)
// PreparePoster gibt das (verkleinerte) Bild zurück
// wird nur beim 1ten Aufruf verkleinert
w := (Width - ((fColumns + 1) * PADDING)) div fColumns;
h := PreparePoster(s, w);
r.Left := (PADDING * x) + (Max(0, (x - 1)) * w);
r.Top := (PADDING * y) + ((y - 1) * h);
r.Right := r.Left + w;
r.Bottom := r.Top + h;
BitBlt(wall.Canvas.Handle, r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top, TBitmap32(s.Poster).Canvas.Handle, 0, 0, SRCCOPY);
// CopyRect war noch langsamer als BitBlt
// FSave.Canvas.CopyMode := cmSrcCopy;
// FSave.Canvas.CopyRect(r, TBitmap32(s.Poster).Canvas, TBitmap32(s.Poster).Canvas.ClipRect);
end;