I'm getting an out of memory exception while looping through images. It happens after about 500 images.
if I try to run the same code through a parallel loop it only makes it through about 5 images.
It usually seems to slow down before throwing the out of memory exception
Here is my code. I'm using MagickNet
public static void PreProductionProcessing(DirectoryInfo dirInfo)
{
var tw = new StreamWriter(@"C:\bar.csv", true);
tw.WriteLine("Filename, Alpha Channel Removed, Dpi Changed, Resized");
foreach (var currentFile in dirInfo.GetFiles("*.tif"))
{
var alphaChannelRemoved = false;
var resized = false;
var DpiChanged = false;
Image img = null;
MemoryStream ms = null;
try
{
img = new Image(currentFile.FullName);
if (img.Matte)
{
ms = RemoveAlphaChanell(currentFile.FullName);
img = new Image(ms);
alphaChannelRemoved = true;
}
if (img.Density.x_res < 300)
{
img.Density = new Image.Resolution(300, 300);
DpiChanged = true;
}
if (img.Size.Width != 1875)
{
var newSize = img.Size;
double resizeRatio = (double)newSize.Width / (double)1875;
newSize.Width = Convert.ToInt16(img.Size.Width / resizeRatio);
newSize.Height = Convert.ToInt16(img.Size.Height / resizeRatio);
img.Resize(newSize);
resized = true;
}
using (var filestream = new FileStream(Path.Combine(@"C:\OutFolder", currentFile.Name), FileMode.CreateNew))
{
img.Write(filestream, "tif");
}
tw.WriteLine("{0}, {1}, {2}, {3}", currentFile.Name, alphaChannelRemoved, DpiChanged, resized);
tw.Flush();
}
catch (Exception e)
{
tw.WriteLine("{0}, {1}", currentFile.Name, e.Message);
tw.Flush();
}
finally
{
if (img != null)
{
img.Dispose();
img = null;
}
if (ms != null)
ms.Dispose();
Magick.Term();
}
}
}
static MemoryStream RemoveAlphaChanell(string source)
{
Bitmap old = new Bitmap(source);
Bitmap temp = new Bitmap(old.Width, old.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(temp);
g.Clear(System.Drawing.Color.White);
var rect = new Rectangle(Point.Empty, new Size(old.Width, old.Height));
g.DrawImage(old, rect);
var stream = new MemoryStream();
temp.Save(stream, ImageFormat.Tiff);
stream.Seek(0, SeekOrigin.Begin);
old.Dispose();
temp.Dispose();
g.Dispose();
return stream;
}
I'm not sure if the memory leak is within MagickNet or if anyone can see anything in my code that is causing this issue.
Any suggestions will be greatly appreciated
When
img.Matte
is true, you replace the image in theimg
variable with a new image. The previous image is never disposed.Dispose the previous image before you replace it: