2010-10-02 4 views
1

J'utilise C# .NET 3.5 et Windows Form J'ai ce code pour gérer la luminosité d'une image, il active lorsque le TrackBar ValueChangesSi j'utilise .Dispose(); pourquoi je continue d'avoir une sortie de la mémoire

public void brightnesstrackBar1_ValueChanged(object sender, EventArgs e) 
{ 
     domainUpDownB.Text = ((int)brightnessTrackBar.Value).ToString(); 
     B = ((int)brightnessTrackBar.Value); 
     pictureBox2.Image = AdjustBrightness(foto, B); 
     foto1 = (Bitmap)pictureBox2.Image; 
    } 


public static Bitmap AdjustBrightness(Bitmap Image, int Value) 
    { 

     Bitmap TempBitmap = Image; 
     float FinalValue = (float)Value/255.0f; 
     Bitmap NewBitmap = new System.Drawing.Bitmap(TempBitmap.Width, TempBitmap.Height); 
     Graphics NewGraphics = Graphics.FromImage(NewBitmap); 

     float[][] FloatColorMatrix ={ 
             new float[] {1, 0, 0, 0, 0}, 
             new float[] {0, 1, 0, 0, 0}, 
             new float[] {0, 0, 1, 0, 0}, 
             new float[] {0, 0, 0, 1, 0}, 
             new float[] {FinalValue, FinalValue, FinalValue, 1, 1 
            } 
      }; 

     ColorMatrix NewColorMatrix = new ColorMatrix(FloatColorMatrix); 
     ImageAttributes Attributes = new ImageAttributes(); 
     Attributes.SetColorMatrix(NewColorMatrix); 
     NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), 0, 0, TempBitmap.Width, TempBitmap.Height, System.Drawing.GraphicsUnit.Pixel, Attributes); 
     Attributes.Dispose(); 
     NewGraphics.Dispose(); 
     return NewBitmap; 
    } 

OK c'est le problème ... si je charge une grande image (comme en pixels par exemple) et commencer à déplacer le trackBar après quelques coups il montrera le fameux "Out of memory exeption was unchanded" et l'erreur pointe vers cette ligne

NewGraphics.DrawImage(TempBitmap, 
     new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), 0, 0, 
     TempBitmap.Width, TempBitmap.Height, System.Drawing.GraphicsUnit.Pixel, 
     Attributes); 

comme vous pouvez tous le voir je dispose. J'essaie d'utiliser

this.SetStyle(ControlStyles.OptimizedDoubleBuffer | 
      ControlStyles.AllPaintingInWmPaint | 
      ControlStyles.UserPaint, true); 

et réglez le tampon double true Mais rien ne résout le problème peut i incrise la quantité de mémoire que le programme utilisera ou il y a une autre façon de résoudre ce problème.

+0

Si vous lancez un profileur (comme memprofiler), je suis sûr que vous trouverez que vous avez des fuites de poignées/ressources GDI ... –

+0

Non, pourquoi le supprimer? C'est de l'information publique. – GManNickG

+0

merci pour la fixation du poste je l'édite et supprime l'info par erreur. – Bloodsville

Répondre

2

Vous fuyez vos images bitmap. Ils ont besoin d'être disposés aussi. Fondamentalement, il suffit de regarder tous les objets que vous utilisez. S'ils implémentent IDisposable, ils doivent être éliminés.

 
public void brightnesstrackBar1_ValueChanged(object sender, EventArgs e) { 
     domainUpDownB.Text = ((int)brightnessTrackBar.Value).ToString(); 
     B = ((int)brightnessTrackBar.Value); 
// TODO: Need to dispose of return value from AdjustBrightness somehow 
// I need more code to figure out where 
     pictureBox2.Image = AdjustBrightness(foto, B); 
     foto1 = (Bitmap)pictureBox2.Image; 
    }

// Note: Returns a Bitmap that must be Disposed public static Bitmap AdjustBrightness(Bitmap Image, int Value) { int width, height; float FinalValue = (float)Value/255.0f; using (Bitmap TempBitmap = Image) { width = TempBitmap.Width; height = TempBitmap.Height; } Bitmap NewBitmap = new System.Drawing.Bitmap(width, height); using (Graphics NewGraphics = Graphics.FromImage(NewBitmap)) { float[][] FloatColorMatrix ={ new float[] {1, 0, 0, 0, 0}, new float[] {0, 1, 0, 0, 0}, new float[] {0, 0, 1, 0, 0}, new float[] {0, 0, 0, 1, 0}, new float[] {FinalValue, FinalValue, FinalValue, 1, 1} };
ColorMatrix NewColorMatrix = new ColorMatrix(FloatColorMatrix); using (ImageAttributes Attributes = new ImageAttributes()) { Attributes.SetColorMatrix(NewColorMatrix); NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), 0, 0, TempBitmap.Width, TempBitmap.Height, System.Drawing.GraphicsUnit.Pixel, Attributes); } } return NewBitmap; }

6

You (appear) to generate a new image, 'NewBitmap', pour chaque mise à jour de la valeur de la trackbar, mais vous ne disposez jamais de cette image().

Essayez d'insérer les points suivants avant pictureBox2.Image = AdjustBrightness(foto, B);

Image oldImg = pictureBox2.Image; 
if (oldImg != null) 
{ 
    oldImg.Dispose(); 
} 
+0

Je l'ai essayé et cela n'a pas fonctionné J'ai eu cette nouvelle exception d'argument de message d'erreur a été désarmée, Paramètre n'est pas valide. Sur cette ligne du code Bitmap NewBitmap = new System.Drawing.Bitmap(TempBitmap.Width, TempBitmap.Height); Bloodsville

+1

@Boodood, Kevin a toujours la bonne approche. Nous ne pouvons pas suivre ce que vous faites avec foto, foto1 etc. –

2

En plus de disposer de tout ce qui est IDisposable (comme Kevin et Aaron ont déjà suggéré), assurez-vous que vous minutage les choses de manière à ne référence aucune objets éliminés après qu'ils ont été éliminés, car ils peuvent ne pas être dans un état invalide/invalide. (Plus sur, par exemple, http://msdn.microsoft.com/en-us/library/8th8381z.aspx.)

Il se produit aussi pour moi que cela pourrait être utile de savoir ce que les foto et foto1 variables sont ...

0

Ok, je vais être en désaccord avec la plupart des les réponses jusqu'à présent (donc je vais probablement avoir tort, mais ici va quand même). Une exception OutOfMemoryException se produit lorsque .Net ne peut plus acquérir de mémoire "gérée". La limite par défaut était d'environ 600 Mo dans .Net 1.0, aucune idée de ce que c'est ces jours-ci. La mémoire "managée" n'a rien à voir avec IDisposable, c'est-à-dire pour les ressources non managées (handles, mémoire non gérée). La mémoire manquée peut manquer de mémoire manquée, mais plus probablement une erreur d'API COM ou Win32 . Cela dit, il est essentiel de disposer des objets IDisposable. Envisagez d'utiliser la construction "using". Regardez-le, c'est l'une des trois utilisations du mot-clé "using". Je pense que certains de ces objets ont aussi une grande empreinte de "mémoire gérée", et que vous les créez trop rapidement pour que le garbage collector puisse y jeter un coup d'oeil. Ma recommandation est que vous envisagiez de créer ces objets une fois puis réutilisez-les.

En fait, au début .Net très gros objets de mémoire gérés jamais nettoyés car vous étiez censé les réutiliser. Depuis lors, je pense qu'ils ont changé cette décision.

Bonne chance.

+0

Oui et non. Essayez d'allouer un grand nombre de bitmaps volumineux dans une application .Net 32 ​​bits, en conservant les références à celles-ci pour qu'elles ne soient pas éliminées. Dans mon expérience, cela conduit rapidement à OutOfMemoryException dans .Net. En examinant, j'ai vu que le gestionnaire de mémoire de Windows ne fait aucune tentative de séparer les adresses de mémoire assignées aux allocations gérées et non managées. Pour cette raison, les allocations non gérées peuvent finir par fragmenter si complètement l'espace de mémoire de processus de 4 Go que .NET ne peut pas allouer le gros morceau de mémoire suivant. – ToolmakerSteve

Questions connexes