C #: Comment réduire la consommation de mémoire et de processeur lorsque vous travaillez avec des bitmaps?

J’ai un projet d’application Windows qui traite de l’édition d’image (rognage et redimensionnement). Malheureusement, ces traitements d’images consumnt beaucoup de ressources en mémoire et en ressources processeur (jusqu’à atteindre facilement 600 Mo ou 50% de l’unité centrale). Il s’agit de rogner et de redimensionner une seule image gif qui pèse 2,5 Mo (2300 * 5400 pixels). De plus, en raison de la consommation importante de ressources, le programme rest bloqué lors du redimensionnement …

public static Image Resize(Image imgToResize, Size size) { Bitmap b = new Bitmap(size.Width, size.Height); Graphics g = Graphics.FromImage((Image)b); g.InterpolationMode = InterpolationMode.Default; g.SmoothingMode = SmoothingMode.HighSpeed; g.PixelOffsetMode = PixelOffsetMode.Default; g.DrawImage(imgToResize, 0, 0, size.Width, size.Height); g.Dispose(); return (Image)b; } public static Image Crop(Image img, Point p1, Point p2) { Rectangle cropArea = new Rectangle(p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.Y); return (img as Bitmap).Clone(cropArea, img.PixelFormat); } 

Quelles méthodes dois-je utiliser pour éviter cela? J’ai déjà essayé de le compresser dans un stream de mémoire en plusieurs formats, mais cela n’a pas aidé (même empiré)

REMARQUE: j’utilise les bibliothèques de dessins .NET standard: System.Drawing, System.Drawing.Imaging

Votre code crée des copies de l’image. Vous devez donc vous attendre à une utilisation accrue de la mémoire non gérée lorsque vous appelez ces méthodes. Ce qui compte beaucoup, c’est ce que vous faites avec l’original. Il serait sage de vous en débarrasser afin que cela ne prenne plus de mémoire. Vous devez appeler sa méthode Dispose () pour le faire. Attendre que le ramasse-miettes le fasse prend trop de temps. La classe Bitmap utilise très peu de mémoire gérée, mais beaucoup de mémoire non gérée.

D’une version antérieure de cette question: http://snippets.dzone.com/posts/show/4336

En outre, AForge.net a plusieurs fonctions de redimensionnement

C’est un problème épineux, et j’en ai déjà rencontré un. Vous pouvez diviser l’image en x morceaux, en fonction de la taille du fichier, puis enregistrer chacun d’eux sur le disque pour vous assurer que la mémoire est propre.

Ensuite, vous redimensionnez les images des composants une par une, à chaque fois, en vous assurant que le composant est disposé avant de passer à la suivante. Une fois que vous avez terminé, vous les assemblez, puis vous les rognez.

Ce problème est majeur: si vous redimensionnez à la hausse , cette approche appenda des coutures à votre image, car l’interpolation n’aura pas à détecter les pixels environnants. Mais je penserais que cette approche fonctionnerait bien avec un redimensionnement à la baisse.

HTH.

Encore un indice:

Par exemple, dans le redimensionnement, comme @Hans l’a souligné, vous créez un nouveau bitmap, lequel correspond à vos goulets d’étranglement.

Mais que se passe-t-il si vous dessinez simplement une image redimensionnée, la même image que celle chargée à l’origine (évidemment, vous avez créé un fichier de sauvegarde de l’image d’origine auparavant sur le disque).

Après le recadrage, que faire si vous dessinez simplement une partie d’un bitmap que cet utilisateur a recadré, ainsi l’utilisateur ne verra que ce rectangle. ?

Je veux dire en général, opère sur l’image que vous avez déjà, et essayez (autant que possible) de ne pas initialiser le nouvel object.

Cordialement.

écrire Application.DoEvents (); dans vos fonctions, au moins ça ne restra pas coincé