11
votes

C # hors de la mémoire lors de la création de bitmap

Je crée une application (formulaire Windows) qui permet à l'utilisateur de prendre une capture d'écran en fonction des emplacements qu'ils choisissent (faites glisser pour sélectionner la zone). Je voulais ajouter un petit "volet de prévisualisation" qui a zoomé dans l'utilisateur afin que l'utilisateur puisse sélectionner la zone qu'ils souhaitent plus précisément (pixels plus grands). Sur un événement de MouseMove, j'ai un code suivant ...

bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);


6 commentaires

Sur quelle ligne votre exception étant votre exception?


Êtes-vous déjà mis en disposition BMPcrop?


Et pourquoi créez-vous une nouvelle image recadrée sur chaque mouvement de la souris au lieu de réutiliser une image existante?


@Steve, Edit: indiquait la ligne qui étant jetée vers l'op @codeinchaos, je dispose de cela juste après la zoombox.invalidate (); Désolé je l'exclua, ajoutera à l'op.


@Codeinchaos, parce que j'ai besoin de l'image / la position mise à jour de la souris.


C'est le mauvais endroit pour le disposer car il n'y a pas de relation individuelle entre invalider les appels et les événements de peinture. Vous devez le disposer directement avant d'attribuer une nouvelle valeur au champ CrocImage . Ou mieux réutiliser l'ancien bitmap et le remplir avec le nouveau contenu.


6 Réponses :


18
votes

Hors de la mémoire en imagerie C # est généralement signe de mauvais rect ou point - un peu de hareng rouge . Je parie start a négatif x ou y lorsque l'erreur se produit ou la taille.Hight + y ou size.Width + x est plus grosse que la hauteur ou la largeur de l'image .


2 commentaires

En regardant le code qui est certainement possible. start.x est Curpos.x - 50 (idem pour la valeur Y). Alors, que se passe-t-il quand Curpos.x ou Curpos.Y de moins de 50 ans?


J'ai vérifié cela, et je pense que vous avez peut-être raison, j'essayais du bord de l'écran ... Alors, ce que je faisais a été essayé du milieu et que cette erreur s'est échappée encore une autre. Le paramètre n'est pas valide. dans mon programme.cs - application ligne.run (); (Je n'ai aucune forme réelle qui est utilisée, sa seule application d'icône de notification.



-2
votes

Si vous créez de nouveaux bitmaps de plus et encore, vous devrez peut-être appeler gc.collect (); qui obligera C # à des ordures collecter


3 commentaires

Je pense que les bitmaps utilisent la mémoire non gérée, alors disposer de la mémoire.


Essayé appelant gc.Collect juste avant zoombox.Image = shownoombox (e.location); Dans la souris, déplacez-vous même et échoue toujours.


Au lieu de GC.Collect, vous devriez disposer () les bitmaps dont vous n'avez plus besoin!



0
votes

Vous devez vérifier si la curlocation.x est supérieure à 50, sinon votre rectangle commencera dans la zone négative (et bien sûr curlocation.y)


1 commentaires

Oui, j'ai besoin d'ajouter cela à mon code, cependant, ce n'était toujours pas la cause de la question.



0
votes

Si la zone de zoom s'éteint le bord de la zone de bureau, lorsque vous essayez de récolter, vous demandez au système de créer une nouvelle image qui inclut des pixels en dehors de la zone de mémoire vidéo. Assurez-vous de limiter votre zone de zoom afin qu'aucun de ses extensions ne soit inférieur à 0 ou supérieur à celui des bords d'écran.


0 commentaires

8
votes

MSDN explique qu'un OutofMemoryException signifie

rect est en dehors des limites de bitmap source

rect est le premier paramètre à la méthode bitmap.clone .

Vérifiez que le paramètre CropArea n'est pas plus grand que votre image.

dans gdi + un OutofMemoryException ne signifie pas vraiment "de mémoire"; Le code d'erreur GDI + Oufofmemory a été surchargé pour signifier différentes choses. Les raisons de cela sont historiques et bien décrites par Hans Passant dans Une autre réponse .


1 commentaires

Dans ce cas, je m'attendrais à ce que .NET fasse la vérification du rectangle transmis avant de passer le code sur le GDI + et de lancer une exception appropriée si le rectangle est invalide.



4
votes

Utilisez l'objet bitmap comme celui-ci:

using (Bitmap bmpImage = new Bitmap(img))
{
    // Do something with the Bitmap object
}


0 commentaires