AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Schnelleres laden von PNGs

Ein Thema von pustekuchen · begonnen am 8. Mär 2012 · letzter Beitrag vom 11. Mär 2012
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.218 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: Schnelleres laden von PNGs

  Alt 8. Mär 2012, 16:15
.. wenn ein bestimmtes Bild geladen/angefordert wurde ist es Dir dann möglich
vorrauszusehen welche(s) Bild/Bilder als nächstes angefragt werden könnten.
Wenn dem so ist, könntest Du einen Thread mit dem Nachladen beschäftigen.
Und hoffen das es nicht kracht. TBitmap verwendet ja ein GDI-Ressourcen und diese sind nur für den Thread gültig indem sei erzeugt wurden.



@pustekuchen: Wieso Arbeitest du nicht durchgehend mit PNG's? Haben ja mit der Semitransparenz einen großen Vorteil gegenübr PNG's.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.779 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Schnelleres laden von PNGs

  Alt 8. Mär 2012, 16:25
.. wenn ein bestimmtes Bild geladen/angefordert wurde ist es Dir dann möglich
vorrauszusehen welche(s) Bild/Bilder als nächstes angefragt werden könnten.
Wenn dem so ist, könntest Du einen Thread mit dem Nachladen beschäftigen.
Und hoffen das es nicht kracht. TBitmap verwendet ja ein GDI-Ressourcen und diese sind nur für den Thread gültig indem sei erzeugt wurden.
O.k, dass war mich nicht so bewusst.

Dann im Thread PNG nach BMP wandeln (das BMP im Thread behalten) und den Inhalt des BMP als MemoryStream an das Hauptprogramm übergeben und dort wieder in ein Bitmap einkopieren.

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Iwo Asnet

Registriert seit: 11. Jun 2011
313 Beiträge
 
#3

AW: Schnelleres laden von PNGs

  Alt 8. Mär 2012, 18:01
Verwende einen Cache, genauer gesagt, einen MRU-Cache. "Most Recently Used". Klingt toll, ist banal:
Du baust Dir eine Liste (verkettet z.B.) mit maximal N Elementen, oder sovielen Elementen, das maximal X Bytes Speicher verbraucht werden.
Die ist zunächst leer.

bevor Du eine PNG in eine Bitmap konvertieren willst, schaust Du im Cache nach, ob die da drin ist. Wenn ja, kommt sie an den ANFANG der Liste. Wenn nicht, wird sie erzeugt und auch an den ANFANG gepackt. Dadurch wächst die Liste. Wenn sie zu groß ist (mehr als N Elemente oder mehr als X Bytes Speicher) wird der LETZTE Eintrag der Liste verworfen.

3-2-1- Perfekt, skalierbar, schnell.

Das tolle ist ja, das die tendentiell oft benötigten Objekte vorne sind, und die selten benötigten eben tendentiell hinten. Also wird ein Cache-Miss relativ selten sein.
  Mit Zitat antworten Zitat
Breager

Registriert seit: 18. Feb 2012
40 Beiträge
 
#4

AW: Schnelleres laden von PNGs

  Alt 9. Mär 2012, 06:32
Immer dieses Rätselraten
Je genauer Du beschreibst, was Du eigentlich vorhast, desto wahrscheinlicher ist, dass Dir jemand helfen kann. Oder ist das ein Geheimnis?

Je nach der Größe einzelner Bilder ist es sinnvoll, diese zu einem großen Bild (Tilemap) zusammenzufassen, das große Bild zu laden und anschließend den entsprechenden Bildausschnitt zu kopieren. Wie werden die einzelnen Bilder angezeigt? In verschiedenen Image-Komponenten oder in einer? Werden die Bilder zufällig ausgewählt, oder ist es absehbar, welche Bilder verwendet werden?

Geändert von Breager ( 9. Mär 2012 um 06:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

Registriert seit: 27. Aug 2010
268 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Schnelleres laden von PNGs

  Alt 9. Mär 2012, 06:44
Vielen Dank für die Zahlreichen antworten =)

.. wenn ein bestimmtes Bild geladen/angefordert wurde ist es Dir dann möglich
vorrauszusehen welche(s) Bild/Bilder als nächstes angefragt werden könnten.
Ja wäre es.

@pustekuchen: Wieso Arbeitest du nicht durchgehend mit PNG's? Haben ja mit der Semitransparenz einen großen Vorteil gegenübr PNG's.
Gut das du mich darauf nochmal aufmerksam machst. Wenn ich mich recht entsinne habe ich es so gemacht, weil ich die PNG nach BMP umwandle, diese einzelteile dann auf eine große Bitmap kopiere und dann einen Teilbereich auf eine Paintbox zeichne. Da gab nachher das Problem, das die Bilder unterschiedliche Farben hatten und das Endergebniss dann ein zusammenengewürfeltes Kunderbunt war. Wenn ich natürlich nun richtig die PNG auf die große Bitmap gezeichnet bekommen, wäre das schonmal ein großer Performance schub.

EDIT: Habs nun nochmal umgeschrieben.
Delphi-Quellcode:
if not Assigned(FPicArray[i - xMin][k - yMin].PngImage) then
          begin
            FPicArray[i - xMin][k - yMin].PngImage := TPNGImage.Create;
            FPicArray[i - xMin][k - yMin].PngImage.Transparent := false;
          end;
          FPicArray[i - xMin][k - yMin].PngImage.LoadFromFile(Path);
Dannach wird das ganze folgendermaßen Kopiert.
Delphi-Quellcode:
BitBlt(Map.Canvas.Handle, xCount, yCount, SIZE_TILE, SIZE_TILE,
            FPicArray[i][k].PngImage.Canvas.Handle, 0, 0, SRCCOPY);
Nun kommen wieder die Kunterbunten Bilder, die dann etwa so aussehen:
Klick

EDIT2: Selbe Problem

Verwende einen Cache, genauer gesagt, einen MRU-Cache. "Most Recently Used". Klingt toll, ist banal:
Du baust Dir eine Liste (verkettet z.B.) mit maximal N Elementen, oder sovielen Elementen, das maximal X Bytes Speicher verbraucht werden.
Die ist zunächst leer.

bevor Du eine PNG in eine Bitmap konvertieren willst, schaust Du im Cache nach, ob die da drin ist. Wenn ja, kommt sie an den ANFANG der Liste. Wenn nicht, wird sie erzeugt und auch an den ANFANG gepackt. Dadurch wächst die Liste. Wenn sie zu groß ist (mehr als N Elemente oder mehr als X Bytes Speicher) wird der LETZTE Eintrag der Liste verworfen.

3-2-1- Perfekt, skalierbar, schnell.

Das tolle ist ja, das die tendentiell oft benötigten Objekte vorne sind, und die selten benötigten eben tendentiell hinten. Also wird ein Cache-Miss relativ selten sein.
Das ist natürlich auch eine sehr gute Idee und würde im meinem Fall wahrscheinlich auch ein wenig helfen und dies werde ich dann auch noch implementieren.
Jedoch ist es ehr so das beim Laden der Bilder am meisten performance verloren geht und dies zuerst optimiert werden sollte.


Immer dieses Rätselraten
Je genauer Du beschreibst, was Du eigentlich vorhast, desto wahrscheinlicher ist, dass Dir jemand helfen kann. Oder ist das ein Geheimnis?

Je nach der Größe einzelner Bilder ist es sinnvoll, diese zu einem großen Bild (Tilemap) zusammenzufassen, das große Bild zu laden und anschließend den entsprechenden Bildausschnitt zu kopieren. Wie werden die einzelnen Bilder angezeigt? In verschiedenen Image-Komponenten oder in einer? Werden die Bilder zufällig ausgewählt, oder ist es absehbar, welche Bilder verwendet werden?
Ja hast schon recht =) Es stelle mit meiner Anwendung eine Karte dar, die aus Tiles besteht. Das zusammenkopieren auf eine Karte und dann einen Bildauschnitt rauszukopieren passiert bereits.

Edit: Das Kopieren geschieht mit BitBlt
Delphi programming is awesome.

Geändert von pustekuchen ( 9. Mär 2012 um 07:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.629 Beiträge
 
Delphi 12 Athens
 
#6

AW: Schnelleres laden von PNGs

  Alt 9. Mär 2012, 07:49
Mangels realen Daten kann ich es nicht ausprobieren, aber ich würde versuchen, die PNGs direkt zu speichern und mit TPngImage.Draw an die passende Stelle zu zeichnen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

Registriert seit: 27. Aug 2010
268 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Schnelleres laden von PNGs

  Alt 9. Mär 2012, 08:16
Die Draw Methode ist aber leider nicht so performant wie BitBlt und in diesem Fall, bei dem oft gezeichnet wird, ist es nicht ausreichend.
Delphi programming is awesome.
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#8

AW: Schnelleres laden von PNGs

  Alt 9. Mär 2012, 20:28
Ermittle die Anzahl der CPUs und erstelle entsprechende Threads, die das Einladen erledigen.
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#9

AW: Schnelleres laden von PNGs

  Alt 9. Mär 2012, 22:00
Zitat:
Die Draw Methode ist aber leider nicht so performant wie BitBlt und in diesem Fall, bei dem oft gezeichnet wird, ist es nicht ausreichend.
Ich würde ohnehin nicht in ein Zielbitmap malen sondern im (On)Paint eines GraphicControls (oder auch einer Paintbox) mit den GDI+ Routinen arbeiten, diese unterstützen nativ 32-Bit und Transparenzen.
http://www.progdigy.com/?page_id=7

2 Units einbinden, nichts installieren ...
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von lbccaleb
lbccaleb

Registriert seit: 25. Mai 2006
Ort: Rostock / Bremen
2.037 Beiträge
 
Delphi 7 Enterprise
 
#10

AW: Schnelleres laden von PNGs

  Alt 10. Mär 2012, 14:03
Vllt. hilft dir auch diese Komponente weiter.

Edit:
An deiner Stelle würde ich die Images gar nicht umwandeln, sondern so mit den PNG´s weiter arbeiten....
Martin
MFG Caleb
TheSmallOne (MediaPlayer)
Die Dinge werden berechenbar, wenn man die Natur einer Sache durchschaut hat (Blade)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:40 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