Reputation: 456
I am trying to combine multiple images to a single one. this is my code right now:
public static Bitmap Merge(List<Image> imgs)
{
int outputImageWidth = 0;
int outputImageHeight = 0;
foreach (var img in imgs)
{
if(outputImageWidth < img.Width)
{
outputImageWidth = img.Width;
}
outputImageHeight += img.Height;
}
outputImageHeight += 1;
using (Bitmap outputImage = new Bitmap(outputImageWidth, outputImageHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
{
foreach (var img in imgs)
{
Graphics graphics = Graphics.FromImage(outputImage);
graphics.DrawImage(img, new Rectangle(new Point(0, outputImage.Height + 1), img.Size), new Rectangle(new Point(), img.Size), GraphicsUnit.Pixel);
graphics.Dispose();
graphics = null;
img.Dispose();
}
foreach (var img in imgs)
{
img.Dispose();
}
GC.Collect();
return (Bitmap)outputImage.Clone();
}
}
While debugging, i figgured out, then whenever I call graphics.DrawImage(...)
about 100-300mb of memory were allocated. I expected it to get liberated whenever i dispose the object, but with every iteration, the process allocates more memory, until I get an out of memory exceptio (approximately after 30 pages on a 32 Bit process).
Any ideas?
Upvotes: 1
Views: 557
Reputation: 21709
Try this instead
public static Bitmap Merge(List<Image> imgs)
{
...
var outputImage = new Bitmap(outputImageWidth, outputImageHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb));
using (var graphics = Graphics.FromImage(outputImage))
{
foreach (var img in imgs)
{
using (img)
graphics.DrawImage(img, new Rectangle(new Point(0, outputImage.Height + 1), img.Size), new Rectangle(new Point(), img.Size), GraphicsUnit.Pixel);
}
return outputImage;
}
}
This
using
blocks that allow for Dispose
to always be called, even if there are exceptions thrown part of the way throughGraphics
throughout the processYou will, of course, have to dispose of the resulting bitmap outside of this method once you're done with it.
Upvotes: 3