i need to resize 5000 images and save them in a separate folder. I have a code like this to create a resized copy of a picture (found on the Internet):
Bitmap ResizeImage(System.Drawing.Image image, int width, int height)
{
var destRect = new System.Drawing.Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
and I have this code, which first creates all the necessary directories to save pictures, and then starts changing all the images and saving them to new folders. In the process of executing the program, my memory starts to fill until it reaches the mark of ~ 590mb (~ 1800 images), and then throws an OutOfMemoryException error.
void ResizeAllImages()
{
var files = Directory.GetFiles(ImagesDirectory, "*", SearchOption.AllDirectories);
if (!Directory.Exists(ResizedImagesDirectory)) Directory.CreateDirectory(ResizedImagesDirectory);
var dirs = Directory.GetDirectories(ImagesDirectory);
foreach(var d in dirs) Directory.CreateDirectory(System.IO.Path.Combine(ResizedImagesDirectory, System.IO.Path.GetFileName(d)));
foreach(var f in files)
{
using(var image = ResizeImage(System.Drawing.Image.FromFile(f), 224, 224))
{
var imgName = System.IO.Path.GetFileName(f);
var dirName = System.IO.Path.GetFileName(System.IO.Path.GetDirectoryName(f));
image.Save(System.IO.Path.Combine(ResizedImagesDirectory, dirName, imgName), ImageFormat.Png);
}
}
}
To solve this problem, I tried to add the following 2 lines of code to the foreach:
GC.Collect();
GC.WaitForPendingFinalizers();
The profiler started to show that during the entire program operation the process takes ~ 50mb, however, when the previous mark of ~ 1800 images is reached, I get an OutOfMemoryException again. How can I solve this problem. Thank you in advance
According to MSDN, the OutOfMemoryException
can be thrown in some non-intuitive situations. For example, it can be thrown in the Bitmap.Clone
method:
OutOfMemoryException: rect is outside of the source bitmap bounds.
We can see that you are not using the Clone method, however you are using a Rect and a Bitmap, and since the memory footprint of your program does not surpass 50MB, we can deduce that the problem is similar.
To really fix this problem, you should first isolate the problematic image, verify exactly what is happening, and then proceed accordingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With