Laden...

Wie kann ich ein Bild, das ich mehrmals verwende, nur 1x in den RAM laden?

Erstellt von HexEdit vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.209 Views
H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 5 Jahren
Wie kann ich ein Bild, das ich mehrmals verwende, nur 1x in den RAM laden?

Hey,

folgende Frage: Wie kann ich ein Bild das ich mehrmals verwende nur 1mal in den RAM laden

dh wenn ich zb:


            for(int i = 1; i < 100; i++)
            {
                this.Content = new Image
                {
                    Source = new BitmapImage(new Uri("Path"));
                };
            }

so lade ich das eine Bild 100 mal in den RAM was nicht so nice ist... wenn ich aber


ImageSource imgScr =  new BitmapImage(new Uri("Patrh"));
private ImageSource GetImage()
{
return imgScr ;
}

            for(int i = 1; i < 100; i++)
            {
                this.Content = new Image
                {
                    Source =  GetImage();
                };
            }

so lade ich das bild leider auch 100 mal in den ram 😦
So, nun zu meiner Frage gibt es einen DatenTyp der Bilde speichern kann ImageSource ist es ja nachdem nicht

Ich hoffe ihr könnt mir helfen.
Danke schonmal im voraus.

4.931 Beiträge seit 2008
vor 5 Jahren

Erstelle nur einmal vor der Schleife das Image-Objekt bzw. ändere deinen 2. Code so ab, daß die Methode GetImage ein Image-Objekt zurückgibt.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 5 Jahren

Image geht nicht da ich im endefekt ein ImageBrush brauche

Würde es dann auch mit ImageBrush gehen
also statt ImageSource ImageBrush

PS: Und die for schleife soll nur symbolisch die mehrfache verwendung des Images darstellen

T
2.219 Beiträge seit 2008
vor 5 Jahren

Welche Grund hast du den dafür?
Wenn nicht wirklich nötig, würde ich die Bilder immer nachladen lassen.
Hier kann sich im einfachsten Fall der Dateisystem Cache des OS um das Caching der Datei kümmern.
Wenn der RAM nicht reicht um ein paar 100 Bilder vom Dateisystem cachen zu lassen, dann nützen die diese im RAM deiner Anwendung erst recht nichts.

Wenn du nur die ImageBrushes brauchst, was deiner Antwort nach der Fall ist, dann kannst du dir auch ganz einfach ein Dictionary mit Key = Dateipfad und Value = ImageBrush anlegen.
Dann musst du in deiner GetImageBrush Methode nur schauen ob die für den Dateipfad schon einen Eintrag hast und kannst direkt den Value aus dem Dictioanry liefern.
Wenn nicht, musst du eben über die ImageSource ein ImageBrush erstellen, Konstruktor dafür sollte vorhanden sein, und dann das ImageBrush ins Dictionary eintragen.
Ist kein Aufwand von einer Minute sowas zu implementieren.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 5 Jahren
  1. Das mit dem Dictionary hab ich schon gemacht das Problem dabei war das es vom RAM her
    nichts gebracht hat (keine Ahnung warumm)

  2. Wenn ich die Bilder immer bei Gebrauch lade sollte ich ja den RAM wieder freigeben, den das Bild verwendet, da das Prgramm ja sonst bei jedem laden der Bilder RAM frisst den es nie wieder freigibt
    sehe ich das richtig?

wenn ja wie kann ich die resourcen des Bildes wieder freigeben

T
2.219 Beiträge seit 2008
vor 5 Jahren
  1. Was soll es auch vom RAM her bringen? Umso mehr du an Bildern Cached um so mehr RAM wird auch von deinem Programm gehalten.

  2. Wenn du zeigst, wie du die bilder lädst und aktuell verwendest, dann kann man vielleicht auch erkennen wo dein Problem liegt.

Mir ist auch aktuell nicht klar was das eigentliches Problem bei dir ist?
Ist der RAM verbrauch deiner Anwendung zu hoch?
Wenn ja, kannst du sicher sagen ob es durch das Bilder laden kommt oder hast du ggf. andere Resourcen die z.B. von IDisposable abgeleietet sind und von dir nicht freigegeben werden?
Oder willst du nur nicht X mal das selbe Bild einladen müssen?
Wenn dies kein Performance/RAM Problem ist und du die Resourcen aktuell korrekt verwendest, warum ist dies ein Problem für dich?

Wenn du kein manuelles Resourcen Handling implementieren willst, kannst du die Bilder auch gerne Cachen.
Nur der Aufwand ist dann bei weitem höher.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 5 Jahren

Was soll es auch vom RAM her bringen? Umso mehr du an Bildern Cached um so mehr RAM wird auch von deinem Programm gehalten.

heißt es ist imprinzip egal ob ich die Bilder mehrmals lade, wenn ja war's ne dumme Frage und es wäre alles soweit geklärt 😄

T
2.219 Beiträge seit 2008
vor 5 Jahren

Das Problem dürfte auch an den CacheOptions sowie die CreateOptions der BitmapImage sein.
Soweit ich dies am Referenz Soruce sehen kann, wird dort bei EndInit auch schon über die Uri intern geschaut ob es bereits eine gecachte BitmapImage gibt und diese wird dann verwendet.

Beim setzen der CreateOption auf None wird die ImageSource aus dem internen Cache entfernt.
Entsprechend sollte damit der RAM verbrauch schon sinken.
Hier musst du dich mal durch die Doku lesen.

Link:
https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.bitmapcacheoption?view=netframework-4.7.2#System_Windows_Media_Imaging_BitmapCacheOption_Default

https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.bitmapcreateoptions?view=netframework-4.7.2

Nachtrag:
CacheOptions auf None setzen sollte reichen, dann lädt er die Datei wohl immer wieder ein und liest sie nicht mehr in den Cache ein.
Hier musst du dir aber dein Objekt auch korrekt selbst bauen, damit die Optionen greifen.
Siehe im Beispiel zu den CacheOptions

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 5 Jahren

danke 😄