![]() |
Schnelles nachladen von Bilddateien
Nabend allerseits.
Wie bereits in meinem Thread über das zeichnen von Semitransparenten PNGs auf den desktop, arbeite ich an einer reprogrammierung des Touhou - BadApple Screensavers. Wem das nichts sagt : ![]() Dank der Hilfe aus dieser Community habe ich es geschafft mit LayeredWindow(s) zu arbeiten. Klappt super und bei 25bildern/sek und einer nativen auflösung von 640*480 des source materials(hatte der original screensaver auch) bin ich schneller als der originale :D: Der originale verbrät 60% meiner CPU, meiner nurnoch 40-50%. Ich weiß aber eine problemstelle bei mir die ich gerne noch behandeln würde: Das laden der Bilder. Immoment habe ich 5478 Pngs in einem ordner die einzeln geladen werden. Das braucht ein "bisschen" performance, von dem was ich weiß behaupte ich sogar es ist das meiste. Könnte ich das mindern, indem ich zb alle bilder in eine datei packe, an den anfang eine tabelle mit den einzelnen daten schreibe(wo welches bild anfängt und wie lange es ist) diese datei in einem filestream öffne und immer die bereiche lade die ich brauche? Was meine bisherigen erfahrungen angeht scheint es zumindest so zu sein dass es langsamer ist durch hunderte von einzelnen kleinen dateien zu rödeln als durch eine große(zumindets merkt man das beim löschen sovieler kleiner bilder, sind nur wenige hundert MBs aber braucht mehr zeit o.O). Obiges geht natürlich nur wenn der filestream beim öffnen nicht gleich alles in den ram knallt ^^". Die möglichkeit Dateien in eine resourcendatei zu packen dient doch nur dazu das chaos zu mindern oder wie wäre es dan damit?! Wen jemand ideen hat, immer her damit :) MFG Memnarch |
AW: Schnelles nachladen von Bilddateien
Keine Sorge, der Filestream knallt nicht alles in dem RAM, sondern arbeitet direkt auf der Festplatte (mal abgesehen vom Windows-Cache). Es ist zu erwarten, dass das Laden schneller geht, wenn alles in einem Stück ist, statt in vielen kleinen Dateien.
Ich würde das eventuell sogar mit einem Thread lösen, und immer in Schritten z.B. fünf Dateien im Hintergrund im Voraus laden, während im Hauptthread die Bilder nacheinander angezeigt werden. Je mehr man in einem Block liest, desto schneller ist das ganze. Natürlich muss man dabei sehr genau auf Synchronisation achten und dafür sorgen, dass der Puffer nicht leer läuft bzw. auf Objekte zugegriffen wird, die noch geladen werden. Und natürlich muss man mal wieder einen Kompromiss aus Performance und Speicherverbrauch finden. [edit] Wenn du die CPU-Last noch weiter reduzieren willst, könntest du eventuell auf OpenGL (oder auch Direct3D) umsteigen, und somit zumindest den Zeichenvorgang an die GPU delegieren. [/edit] |
AW: Schnelles nachladen von Bilddateien
also von dem gemessenen sind kanp 50% der genutzten leistung, ladeleistung^^.
Das im block laden wird schwierig da ich nicht wirklich chronologisch durchgehe. Ich messe die millisekunden seit starte und errechne daraus das bild da sich anzeigen muss(is ja schön durchnummeriert ;) ). Somit gewährleiste ich unter allen umständen eine saubere synchronisation von audio und bild. MFG Memnarch |
AW: Schnelles nachladen von Bilddateien
Du kannst ja eine threadsichere Liste nehmen und die Bildnummer als Index benutzen. Beim Start reservierst du in der Liste bereits den Speicher für alle Einträge, setzt sie aber erst mal auf nil. Dann startest du den Preloader-Thread, der die Bilder lädt und in die Liste einfügt. Wenn genügend Bilder gepuffert sind, fängst du an, die Bilder wie gewohnt anzuzeigen. Nach dem Anzeigen das Bild per Free wieder freigeben. Wenn die Liste für den aktuellen Index nil zurückgibt, musst du das Bild erst laden. Dem Preloader-Thread sollte man in diesem Fall auch noch irgendwie mitteilen, dass er hinterherhinkt.
|
AW: Schnelles nachladen von Bilddateien
Mh, interressante idee. Ne threadsichere liste, gibts da schon was oder muss ich da erst ran o.O(bei letzterem wirds haarig:stupid:)
|
AW: Schnelles nachladen von Bilddateien
Ich würd's mal mit
![]() |
AW: Schnelles nachladen von Bilddateien
Joar..eindeutiger name, nech?^^.
Werde ich mir nach ner mütze schlaf mal angucken(und nachdem alles in einer datei verstaut werden kann :P). Noch 2 dinge: 1) Meine bilder haben eine gesamtgroße von 500MB. jpg wärens nur 130MB, aber kein Alphakanal >.<(der muss sein). 2) etwas das ich mal ausprobiert aber wieder verforfen hatte(weil sowieso blöde idee :D), ABER: ich hatte mal versucht einfach alle bilder in den ram zu klatschen. Ein bild geladen-> ab in eine tobject liste. IMMER nach exakt 260 Bildern war schluss, ungültiges bild. Das programm hatte da vllt 500KB ram eingenommen. Bin hier unter WIn7 und hattes es auchmal als Admin gestartet. Wüsste gerne für später mal was da los ist o.o. EDIT: wnen es sowieso generell schneller ist alles aus einer datei zu laden, wie stehts dann damit, dass ich einfach alles chronologisch in die resourcen packe und daraus lade o.O. Oder hat der filestream da noch vorteile?(den ich bei einem eigenen format genommen hätte) MFG Memnarch |
AW: Schnelles nachladen von Bilddateien
Ich glaube, der Taskmanager zeigt nicht den gesamten belegten Arbeitsspeicher an, sondern nur den, der sich tatsächlich auch um RAM befindet. Ausgelagerter Speicher ist glaube ich nicht mit eingerechnet. Du kannst dir mal den Process Explorer von Sysinternals laden, der zeigt beides an.
Muss der Alphakanal denn wirklich sein? Wenn dein Material einfarbig ist wie im verlinkten Video, würden doch 2 Farben eigentlich reichen, oder? |
AW: Schnelles nachladen von Bilddateien
Auf den erstenblick scheint es nur 2farbig(wär ja schön, Monochrome map und transparentefarbe drüber), aber es gibt auch graustufen :P
Z.B. der schattenwurf bei dem intermezzo der drei damen ist semitransparent wie auch noch so einige dinge. (gibt halt farbverläufe von weiß nach schwarz). Leider kommt da ne monochrome map nicht infrage >.< THEORETISCH wäre es möglich NUR den alpha kanal zu nehmen. Aber da wüsste ich nich wie :P (das möglich bezieht sich auf die getreue darstellung des bildes) PS: und könnte ich auch anstatt nem eigenen format auch das ganze in ne resourcefile klatschen?(oder färe es per filestream doch besser es selbst zu handeln?) PSS: Guten morgen^^ (wo bleiben nur meine Manieren :stupid: ) PSSS: Und wnen ich es, wie oben erwähnt habe, schaffen würde NUR den alphakanal abspeichern und verwenden zu können. Dan wären nur ca 160MB übrig, schnelleres laden, schnellere performance.(also ich würd eigentlich mit 8Bit pro pixel auskommen..nur wie >.<) PSSSS: IDEE: was passiert, wenn ich den Alphawert nach dem laden eines PNG "Manuell" bestimme? da ich hier ja nur schwarz-> weiß habe, kann ich doch auch einfach z.b den AlphaKanal = Red setzen oder nicht? MFG Memnarch |
AW: Schnelles nachladen von Bilddateien
Es ist möglich, PNGs als Graustufen zu speichern, was dann quasi dem Alphakanal entspräche. Ich würde einfach alle Bilder hintereinander in einen Stream klatschen, dann kann man die bequem in einer Schleife laden (wenn ein Bild fertig geladen ist, ist der Stream direkt am Anfang des nächsten Bildes positioniert) und hat keinen Overhead.
[edit] ![]() |
AW: Schnelles nachladen von Bilddateien
5478 Pngs ist schon ein klein wenig viel. Aber mal ne Frage: Wenn du das Bild aus einem Stream ließt, ist es ja immernoch ein PNG-Bild. Heißt Delphi kann damit nicht von Haus aus umgehen und braucht Fremdkomponenten. Diese brauchen jetzt vom Laden bis zum Umsetzen auch ein klein wenig Zeit.
Ist es denn nicht ein Versuch wert, mit Fenster-Regionen zu arbeiten? Ein kleines Beispiel findest du hier: ![]() ![]() Bernhard |
AW: Schnelles nachladen von Bilddateien
@Rollstuhlfahrer: Mit Regionen kannste nur dein Fenster in eine gewünschte form zerschnipseln, aber KEINE semitransparenz o:O. BMP...wen ich das nehme explodiert der speicher^^.
@Namenloozer. MH okay greayscaled. Hatte mal in GIMP ein bild nach greyscaled konvertiert, aber hatte absolut keinen unterschied in der größe gemacht^^". Muss ich nochmal gucken. EDIT: @Namenloozer: Wgen meiner sync technik muss ich sowieso eine tabelle an den anfang schreiben um praktisch einen index aller files zu bekommen ;) MFG Memnarch |
AW: Schnelles nachladen von Bilddateien
Wirst du bzw. könntest du das dann veröffentlichen (exe; src ist mir egal...)? Es ist interessant, den Entwicklungsstand mitverfolgen zu können =D
|
AW: Schnelles nachladen von Bilddateien
Ich hätte einen Vorschlag.
Wenn es nur um eine Maske geht, kannst du vllt. ja auch ein eigenes Dateiformat verwenden, wodurch du den Speicherverbraucht drastisch senken könntest (1 Byte je Pixel). Die Frage ist dann nur, wie du das Bild dann schnell auf den Bildschirm anwenden könntest... MFG Björn |
AW: Schnelles nachladen von Bilddateien
1 Byte je Pixel? Das wäre doch immer noch riesengroß bei 5000 Bildern. Damit wirst du niemals einen geringeren Speicherverbrauch erreichen als mit PNG... Wenn dann würde ich zumindest eine RLE-Kodierung verwenden, das sollte bei dieser Art von Bildern auch schon recht viel Platz sparen, und hat den Vorteil, dass es sich schnell dekodieren lässt.
|
AW: Schnelles nachladen von Bilddateien
@Aphton: Ja ich release das fertige projekt WENN es fertig ist^^.
Das mit dem 1Byte pro pixel wäre optimal, aber leider geht das wohl standartmässig mit PNGs nicht >.<. Und jetzt hab ich mich doch glatt verhaspelt XD. Hab alles in eine datei gepackt, und kenne beim auslesen startpunkt und länge jedes bildes. Wie lade ich das jetzt wieder richtig^^". Vllt in eine Memorymappedfile lesen und dann der entsprechenden bildkomponennte zuweisen o.O EDIT: hat schon geklappt, mit TMemoryStream :) |
AW: Schnelles nachladen von Bilddateien
Zitat:
|
AW: Schnelles nachladen von Bilddateien
Gut okay(dan habe ich wohl nicht richtig gelesen) aber wie bekomme ich die jetzt hin?
Ich meine ich habe hier seeeeehr viele bilder. Im moment 32bit RGBA(aus Vegas gerendert). Gibt es da nen tool mit dme ich das mit allen "gleichzeitig" machen kann o.O. Noch ein problem: Bisher habe ich TGPImage benutzt, das kann abe rnicht so ohne weiteres aus einem Memorystream lesen. (meine aktuelle funktion gibt einen memorystream mit den daten des gewünschten bildes zurück). Hatte dann gedacht auf TPNGImage umzusteigen, aber...dann kriege ich bei der übertraging von TPNG nach TBitmap per draw dochwieder nen geschwindigkeitsverlust oder? MFG Memnarch |
AW: Schnelles nachladen von Bilddateien
Hallo,
auch TGPImage kann aus einem Stream lesen, natürlich nicht aus einem Delphi-Stream, aber aus einem IStream. Mit ![]() Gruß xaromz |
AW: Schnelles nachladen von Bilddateien
Ja adarauf war ich schon gestosse, da hatten man aber wohl probleme das richtig in dne istream zu bekommen weil delphi das nicht so gut implimentierte(oder so ähnlich) war vllt nen älterer beitrag, ich buddle habs datum nich gemerkt^^"
Werds mir nochmal angucken. PS: jemand ne idee wo ich eine einführung finde wie ich in Delphi mit DirectX einfach images auf dem bildschirm zeichne? Die einführungen die ich fand, fangen immer zielgerichtet auf 3d an, aber das bring tmich wneig weiter :( (DX mal ausprobieren wie sich das mit meinem projekt verträgt :P) |
AW: Schnelles nachladen von Bilddateien
Direct3D und OpenGL sind, wie der Name schon vermuten lässt, Frameworks für 3D-Grafik und nicht für den 2D-Bereich. Das lässt sich auch nicht einfach umstellen. Bei OpenGL gibt es aber eine Funktion, die der Welt sagt, dass sie flach ist und dementsprechend auch keine Tiefe gezeichnet wird. Sowas wird es für Direct3D auch geben (hab ich so im Gefühl).
Bernhard |
AW: Schnelles nachladen von Bilddateien
Man kann sowohl OpenGL als auch Direct3D ohne Probleme für 2D benutzen. Sogar die Windows-Oberfläche selbst basiert ab Vista auf Direct3D. Für OpenGL gibt's ein
![]() |
AW: Schnelles nachladen von Bilddateien
SO, also irgendwas mache ich hier falsch:
Code:
Kurz vorweg: Packhelper ist eine selbtgeschriebene klasse, die in dder Lage ist, dateien in meine Packete reinzupacken und rauszuholen.
procedure LoadIdToImage(AId: Integer; ABitmap: TBitmap);
var Image: TGPImage; LStream: TMemoryStream; LStreamAdapter: TStreamAdapter; begin LStream := TMemoryStream.Create; PackHelper.GetPackItem(AId, LStream); LStream.seek(0,soFromBeginning); LStreamAdapter := TStreamAdapter.Create(LStream, soReference); Image := TGPImage.Create(); Image.FromStream(LStreamAdapter); try GPImageIntoBitmap(Image, ABitmap); finally Image.Free; LStreamAdapter.Free; LStream.Free; end; end; Die GetPacketItem holt für den angegebenen Index die daten und packt sie in den übergebenen MemoryStream. GPImageIntoBitmap ist wie das Original von Xaromz, nur wird hier keine Bitmap zurückgegeben sondern in eine vorhandene übertragen. GPImageIntoBitmap funzt ganz sicher, die benutze ich nämlcih auch, wnen ich TGPImage direkt von der Platte lade. Der stream der von meinem PackHelper übergeben wird, scheint auch in ordnung zu sein. Ich haben den Erhaltenen Memorystream zu testzwecken einfach direkt als png file abgespeichert, resultat war die angeforderte Bildatei und schien auch OK zu sein. Mach ich da oben was beim TSreamadapter komplett falsch? Oder darf ich dne garnicht direkt übergeben? Sondenr muss das erst in einen IStream clonen ? DAs problem ist nämlch, dass ich am ende eine "Ungültige Zeigeroperation" bekomme >.< EDIT: achherje, habe gerade gesehen das CLONE nichteinmal implimentiert ist o.O. Aber hier gibts ne lösung die ich mal Probieren werde: ![]() EDIT: nö klappt nochimmer nicht >.<. EDIT2: schon gelöst, ich musste den TStreamAdapter constructor auf ein ISTREAM objeckt und auf kein TStreamAdapter anwenden XD MFG Memnarch |
AW: Schnelles nachladen von Bilddateien
Vielleicht noch so am Rande, der Original-Screensaver arbeitet wohl auch mit diesen Regionen. Man kann nämlich die Maus in den Flächen bewegen, wo der Desktop durchscheint und der Screensaver beendet sich nicht. Nur wenn zwischendurch eine schwarze Fläche in den Weg gerät. Heißt, du bräuchtest all diese Bilder gar nicht. Du kannst dir eine Masken-Datei anlegen und somit dein schwarzes Form immer wieder anpassen.
So kommst du auch auf die angesprochenen 1 Byte / Pixel. Wenn du diese Datei (bei mir sind es 0en und 1en) noch komprimieren lässt (GZip, Zip, etc.) kommst du am Ende auf weniger als 1 Byte / Pixel. Ich werde dich jetzt nicht zwingen, das exakt so zu machen. Deine Methode hat auch was. Bernhard |
AW: Schnelles nachladen von Bilddateien
Zitat:
|
AW: Schnelles nachladen von Bilddateien
Die regionen stelle ich mir eher problematischer for, weil aufwändiger. Zweitens können regionen doch eig. gar nicht semitransparent sein oder?
Muss auch nochmal eben etwas ausprobieren, aber ein layered windows ist an 100% durchsichtigen stellen, auch durchklickbar ;). Das erledigt windows perpixel automatisch^^ EDIT: und wenn er regionen nutzen würde, würde er ein vektorformat zum speichern nutzen und dann wäre der originale screensaver doch nicht 160MB oder o.O MFG Memnarch |
AW: Schnelles nachladen von Bilddateien
Vorhin im NAS ausversehn drüber gestolpert.
Nja, auf 4K sah es erstmal schlimm aus, aber installiert und in den Einstellungen die Qualli hochgeschraubt, geht es schon noch halbwegs. Schon interessant, dass dieses Video über all die Jahre immernoch aktuell ist und immernoch welche damit rumspielen. Mit FlipDisplay, auf uralten 8-Bit-Spielekonsolen oder eine KI (StableDiffusion) drübergejagt und dort farbige Figuren reingerändert (anhand von bunten Bildern der Figuren). [edit] Ups, wollte eigentlich dort ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:32 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