Hallo Community,
Ich möchte gern ein ListView mit einer ImageList erstellen und diese anzeigen.
Jedoch habe ich dabei das Problem, dass der Speicherverbrauch (RAM) bereits bei einem geladenem Bild (~3MB) auf 53 MB (vor dem Laden: 17MB) steigt.
Anbei mein Code:
private void AddImage(string sFilePath)
{
Image newImage = Image.FromFile(sFilePath);// Viele Bilder: OutOfMemory Exception
newImage.Tag = GetFileNameFromPath(sFilePath);
imageList.Images.Add(newImage.Tag.ToString(), newImage);
lPathsOfImagesToScale.Add(sFilePath);
ListViewItem currentItem = new ListViewItem(sFilePath);
currentItem.ImageIndex = imageList.Images.Count - 1;
ctrlImagePreviewBox.Items.Add(currentItem);
newImage = null;
}
Der Speicherverbrauch schnellt an der Stelle
Image newImage = Image.FromFile(sFilePath);
wie oben beschrieben in die Höhe.
Bzgl. "Bildverarbeitung" bin ich leider noch ein absoluter Anfänger und ich habe das Laden der Bilder auf die einfachste Art und Weise implementiert und möchte es gern optimieren.
Leider weiß ich nicht, wie optimierbar der Code noch ist, da ich das Bild ja nicht irgendwann wieder freigebe, sondern ein Verweis darauf stetig in der ImageList hinterlegt ist.
Ideen? Vorschläge?
Aller Wahrscheinlichkeit nach wird das Weltall von einem Rudel Irrer regiert.
Hi,
zuerstmal: Dein Bild ist zu groß. Speicher und lad es entsprechend der in der ImageList gespeicherten Größe - das dürfte ein wenig helfen.
Was Images laden über die von dir verwendete Methode angeht habe ich
schleche Erfahrungen gemacht.
Kam bei der Arbeit des Öfteren zu GDI+ Exceptions - angeblich wegen irgendwelcher Locks...
Ich les Bilder wenn ich diese selbst lade in ein byte-Array und zaubere dann daraus ein Bild.
Woran dieser enorme Speicherzuwachs genau liegt... kA...
Zudem bietet die ImageList an eine niedrigere Qualität für Bilder zu verwenden - wann das geschieht wäre interessant - möglich wäre, dass die ImageList dein Bild z.B. sogar noch mal kopiert und dein eigentliches Bild unnötig macht...
Das wärn die paar Sachen die mir dazu einfallen.
LG
Achim
Woran dieser enorme Speicherzuwachs genau liegt... kA...
Das wird wohl daran liegen, dass das Bild im Arbeitsspeicher verschwindet? 😉
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Hi,
Bei 3/6 oder sogar 9 MB sicherlich gerne am Bild inkl. 1 oder 2 Kppien 😉
Da wir hier allerdings doch von ein wenig mehr reden kann das (eig) nicht (nur) am bild liegen.
So denk ich jedenfalls...
LG
Achim
Hi,
zuerstmal: Dein Bild ist zu groß. Speicher und lad es entsprechend der in der ImageList gespeicherten Größe - das dürfte ein wenig helfen.
Danke, ich werde mir dann wohl eine kleine Thumbnail Methode Stricken, oder gibt es im.NET Framework bereits eine Methode die diese Funktion implementiert?
Vorab eine Frage: diesen "Anstieg" hast du im Taskmanager beobachtet?
Jep - ist das nicht aussagekräftig genug? Mein Problem ist, dass ich diesen Aufruf für mehrere Bilder in einer Schleife mache. Das führt dann irgendwann dazu, dass ich von genau dieser Stelle eine OutOfMemoryException geworfen bekomme.
Ich kann mir nicht so recht vorstellen, warum die ImageList sich Kopien erstellen sollte, aber nichts desto trotz. Gebe ich das Image Objekt explizit mit Dispose() wieder frei erscheinen die Bilder auch nicht mehr in der ImageList.
Der Speicherverbrauch steigt auch nicht beim Zuweisen des Image Objekts an de ImageList so stark an, sondern beim Aufruf von Image.FromFile(...).
Aller Wahrscheinlichkeit nach wird das Weltall von einem Rudel Irrer regiert.
ich werde mir dann wohl eine kleine Thumbnail Methode Stricken, oder gibt es im.NET Framework bereits eine Methode die diese Funktion implementiert?
Ja, gibt es.
Jep - ist das nicht aussagekräftig genug?
Jep. Vergiss den Taskmanager, wenn du mit .NET den Speicherverbrauch messen willst.
Das führt dann irgendwann dazu, dass ich von genau dieser Stelle eine OutOfMemoryException geworfen bekomme.
Die Bilder liegen natürlich in ihrer Origianlgröße im Arbeitsspeicher. Da sie vermutlich mehr als die 85k Speicher verfressen, liegen die auch noch im LOH, was sich auch negativ auf die effektivität des Speichermanagements auswirkt.
Wieviel in MB sind denn alle Bilder zusammen, die du laden willst?
Wieviel in MB sind denn alle Bilder zusammen, die du laden willst?
Es können schon (weit) über 100 MB zusammen sein.
Aller Wahrscheinlichkeit nach wird das Weltall von einem Rudel Irrer regiert.
Hallo inva,
Es können schon (weit) über 100 MB zusammen sein.
100 MB (JPEG-/PNG-)komprimiert oder 100 MB entkomprimiert?
Ist aber eigentlich auch egal, denn die Lösung wurde ja schon genannt.
herbivore
2 GB könnten auch vorkommen - im ersten Fall könnte ich eventuelle Referenzen wieder freigeben und bei Bedarf neu allokieren.
Aber, was ich mich frage, wie macht es der Windows Explorer? Er verfügt ja auch über eine Miniaturansicht, und selbst wenn x-beliebig viele Bilder in einem Ordner sind, zeigt er brav alle an, er lädt sie zwar erst in dem Moment, wenn ich sie scrolle, aber einmal geladen sind sie persistent in der Miniaturansicht. Ich wollte prinzipiell das gleiche Verhalten wie die Windows Explorer Miniaturansicht implementieren (aber erstmal ohne das Laden bei Bedarf).
Aller Wahrscheinlichkeit nach wird das Weltall von einem Rudel Irrer regiert.
Hallo,
der Explorer zeigt ja als Miniaturansicht nicht das Originalbild sondern ein Thumbnail-Image davon an (also ein kleines Bild). Daher auch die versteckte thumbs.db Datei indem Ordner wo diese gecached werden.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Vielleicht um das nochmal explizit zu erwähnen: Wirf die Bilder möglichst schnell wieder aus dem Speicher (mittels Dispose bzw. using
) und halte nur ein Thumbnail im Speicher, das du via GetThumbnailImage erzeugst.
Für die Thumbs.db gibt's zwar Parser auf Codeproject, sie existiert aber nur unter XP - Vista / 7 haben da eine andere Datei.
Hier ist meine GetThumbnail-Methode drin.
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
der Explorer zeigt ja als Miniaturansicht nicht das Originalbild sondern ein Thumbnail-Image davon an (also ein kleines Bild). Daher auch die versteckte thumbs.db Datei indem Ordner wo diese gecached werden.
D.h. dann doch aber, dass ich, wenn ich nur genügend Bilder in einem Ordner habe, auch im Explorer eine OutOfMemoryException produzieren könnte?
Vielen Dank an euch!
Die Idee bzgl. der Thumbnails werde ich aufgreifen. Ich dachte ich mache eventuell generell etwas falsch oder es gibt einen effizienteren Weg - aber eigentlich hätte ich da auch selber drauf kommen können. Nichts desto trotz, vielen Dank! 😃
Aller Wahrscheinlichkeit nach wird das Weltall von einem Rudel Irrer regiert.
D.h. dann doch aber, dass ich, wenn ich nur genügend Bilder in einem Ordner habe, auch im Explorer eine OutOfMemoryException produzieren könnte?
Unwahrscheinlich - der Explorer entlädt auch Thumbnails, die er nicht braucht, wieder.