I have a Windows Application project that deals with Image editing (Cropping & Resizing). Unfortunately these image processings consume a lot of Memory and CPU resources (easily reaches 600MB or 50% cpu) and it is all about cropping and resizing just one gif image that weighs 2.5MB (2300*5400px). More than that, due to large resource consumption, the program gets stuck while resizing...
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);
}
What methods should I use to avoid this? I've already tried compressing it to memory stream in several formats but it didn't help (even made it worse)
NOTE: I use the standard .NET Drawing libraries: System.Drawing, System.Drawing.Imaging
Your code is creating copies of the image so you should expect unmanaged memory usage to rise when you call these methods. What matters a great deal is what you do with the original. You would be wise to get rid of it so it no longer takes up memory. You have to call its Dispose() method to do so. Waiting for the garbage collector to do it takes too long. The Bitmap class takes very little managed memory but oodles of unmanaged memory.
This is a tricky one, and one I've run into before. You could split the image into x pieces, depending on the size of the file, then save each one to disk to ensure that the memory is clean.
Next, you resize the component images one at a time, each time, ensuring that the component is disposed before proceeding to the next one. Once you're all done, you stitch them back together, and then crop.
A MAJOR PROBLEM with this approach - if you're resizing upward, this approach will put seams in your image, as the interpolation won't have the surrounding pixels to guess at. But I would think that this approach would work well with resizing downward.
HTH.
From an earlier version of this question: http://snippets.dzone.com/posts/show/4336
Also, AForge.net has several resize functions
Another hint again:
For example in resize, like @Hans pointed out, you create a new Bitmap, which one is your bottlenecks.
But, what if you just draw image resized, the same image which was loaded originally (obviously you made a backup file of original image before on the disk).
After crop what if you just draw a portion of a bitmap that user cropped, so user will see only that rectangle. ?
I mean in general, operate over image you already have, and try (as much as it possible) do not initialize new object for it.
Regards.
write Application.DoEvents(); in your functions, at least it wont get stuck