Speicher explodiert ?

JJB

Cogito ergo brumm
Hallo zusammen,

ich hab da mal ne blöde Frage.
Und zwar möchte ich mit einer Picturebox durch eine Reihe von Photos "zappen".
Dazu lade ich ein Image bzw. Bitmap mit einem File und werfe es in die PictureBox. Nach drücken einer Taste, z.B. Pfeil-Rechts, hole ich das nächste Bild. Warum erreiche ich schon nach wenigen Bildern 1,6 GB Arbeitsspeicher, was unweigerlich zum Absturz führt ?

Ist es so komplex Bilder in eine PictureBox zu laden ?
Wie muss ich mit den Bildern, bzw. dem Speicher umgehen um hier nicht zum Speicherfresser zu werden ?

Danke !
 
V

VScan

Hey,


hast du Code? Das Laden der Bilder ist normalerweise nicht aufwendig, naja, kommt drauf an wie groß die sind :)


LG
 

JJB

Cogito ergo brumm
Tach,

ich hab den Code nicht zur Hand. Ist an sich nicht viel, ich mach das mal jetzt so aus dem Kopf. Hoffe es passt einigermaßen:
Code:
if (e.KeyCode == "Keys.Right")
{
   Bitmap myBitmap = new Bitmap(myFileName);
   int myBmpWidth = myBitmap.Width;
   int myBmpHeight = myBitmap.Height;

   while ((myBmpWidth > myPictureBox.Width) || (myBmpHeight > myPictureBox.Height))
   {
      myBmpWidth *= 0.9;
      myBmpHeight *= 0.9;
      myBitmap = new Bitmap(myBitmap, new Size(myBmpWidth, myBmpHeight));
   }

   myPictureBox.Image = myBitmap;
}

Ich hab so den Verdacht, es könnte an der Skalierung liegen.
Die Bilder sind jpg bei 4000x2500 oder so ähnlich.
Ungeachtet des Code Schnipsels; wie ginge das denn, wenn man es richtig macht ?
 

tombe

Erfahrenes Mitglied
Wenn die Bilder skaliert werden müssen, erstellst du in der While Schleife ja unzählige neue Bildobjekte.

Das wird der Grund sein warum der Speicher überläuft.

Vielleicht hilft dir das hier ja weiter.
 
Zuletzt bearbeitet:

CPoly

Mitglied Weizenbier
Eigentlich sollte dein Speicherproblem schon gelöst sein, wenn du die eine Zeile aus der Schleife raus nimmst und noch das alte Bild aus der PictureBox frei gibst:

C#:
if (e.KeyCode == "Keys.Right")
{
   Bitmap myBitmap = new Bitmap(myFileName);
   int myBmpWidth = myBitmap.Width;
   int myBmpHeight = myBitmap.Height;
 
   while ((myBmpWidth > myPictureBox.Width) || (myBmpHeight > myPictureBox.Height))
   {
      myBmpWidth *= 0.9;
      myBmpHeight *= 0.9;
   }

   myBitmap = new Bitmap(myBitmap, new Size(myBmpWidth, myBmpHeight));
 
   Image img = myPictureBox.Image;

   myPictureBox.Image = myBitmap;

   if(img != null)
      img.Dispose();
}

Aber: teste mal http://msdn.microsoft.com/en-us/library/system.windows.forms.picturebox.sizemode.aspx

Edit: Abgesehen davon, brauchst du die Schleife gar nicht, weil du mit einfachem Dreisatz auf die exakte Lösung kommst. Denn deine Schleife ist ja auch nur eine schlechte Näherung (immer wieder 90% ?). Genau das wird in tombe's Link gemacht.
 
Zuletzt bearbeitet:

JJB

Cogito ergo brumm
Hi

naja, der Code war nur mal so ad hoc aus dem Kopf.
Ich glaube der Skalierungsfaktor war wesentlich kleiner. Ich lag im Bereich von maximal 3-4 Iterationen. Müsste also etwas zwischen 0.5 und 0.75 gewesen sein. Das Bitmap sollte nach der Schleife erstellt werden.
Der Punkt ist, ich habe nach mehreren Bilder keinen Speicher mehr. Er wird einfach nicht mehr freigegeben.

Muss ich irgendetwas berücksichtigen, um sicher zu gehen, dass alte Bilder nicht im Speicher verbleiben ? Oder ist der Einsatz von Bitmap generell von Nachteil ?
Vielleicht liegt es auch am Füttern der PictureBox ?
 
Zuletzt bearbeitet:

JJB

Cogito ergo brumm
V

VScan

Hey,

vielleicht bringts ja was, wenn du den Speicher mit 'ner "using"-Direktive oder so wieder frei gibst, nachdem du das Bild bearbeitest hast, möchte wetten die Bitmap-Class implementiert IDisposable.

Code:
using (Bitmap myBitmap = new Bitmap("myFileName"))
{
       ...
}


MfG
 

JJB

Cogito ergo brumm
Siehe da, es ward Licht !

Ich habe das Image der PictureBox immer auf null gesetzt, bevor ich das neue Bild geladen habe.
Wenn ich statt dessen das alte Bild in ein Image kopiere und dieses per Dispose leere wird unmittelbar darauf, der belegte Arbeitsspeicher freigegeben. Das mache einen immensen Unterschied.

Im Nachhinein gesehen liegt das doch recht nahe. Hätte ich gleich drauf kommen sollen.

Danke nochmals !