I have some parallel.for
one inside another.
the last parallel.for
have a normal for
that should Create images by combining other images.
the images are generated but the memory consumed by the process slowly increases.
I'm using net core 6, and as you can see I have dispatched all the Bitmaps and the Graphics objects.
also I'm forcing garbage collection so the memory stop growing (I ran the code for 4 hours without forcing collection and the dispatched objects were not collected)
here is the code:
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
Console.WriteLine("Generando!");
var count = 0;
Parallel.For(1, 11, (a) =>
{
Parallel.For(1, 11, (b) =>
{
Parallel.For(1, 11, (c) =>
{
Parallel.For(1, 11, (d) =>
{
Parallel.For(1, 11, (e) =>
{
for (int f = 1; f <= 10; f++)
{
Bitmap source1 = new Bitmap($"1/{a}.png");
Bitmap source2 = new Bitmap($"2/{b}.png");
Bitmap source3 = new Bitmap($"3/{c}.png");
Bitmap source4 = new Bitmap($"4/{d}.png");
Bitmap source5 = new Bitmap($"5/{e}.png");
Bitmap sourceBase = new Bitmap($"Rostro Base.png");
Bitmap source6 = new Bitmap($"6/{f}.png");
var target = new Bitmap(source1.Width, source1.Height, PixelFormat.Format32bppArgb);
var graphics = Graphics.FromImage(target);
graphics.CompositingMode = CompositingMode.SourceOver; // this is the default, but just to be clear
graphics.DrawImage(sourceBase, 0, 0);
graphics.DrawImage(source6, 0, 0);
graphics.DrawImage(source5, 0, 0);
graphics.DrawImage(source4, 0, 0);
graphics.DrawImage(source3, 0, 0);
graphics.DrawImage(source2, 0, 0);
graphics.DrawImage(source1, 0, 0);
count++;
var nombre = $"{count}_{a}-{b}-{c}-{d}-{e}-{f}";
var target2 = Cropimage(target);
target2.Save($"rostros/{nombre}.png", ImageFormat.Png);
source1.Dispose();
source2.Dispose();
source3.Dispose();
source4.Dispose();
source5.Dispose();
source6.Dispose();
sourceBase.Dispose();
target.Dispose();
target2.Dispose();
graphics.Dispose();
GC.Collect();
}
});
Console.Write($"\r{count} imagenes generadas ");
});
});
});
});
Bitmap Cropimage(Bitmap input)
{
// Find the min/max non-white/transparent pixels
Point min = new Point(int.MaxValue, int.MaxValue);
Point max = new Point(int.MinValue, int.MinValue);
for (int x = 0; x < input.Width; ++x)
{
for (int y = 0; y < input.Height; ++y)
{
Color pixelColor = input.GetPixel(x, y);
if (pixelColor.A > 0)
{
if (x < min.X) min.X = x;
if (y < min.Y) min.Y = y;
if (x > max.X) max.X = x;
if (y > max.Y) max.Y = y;
}
}
}
// Create a new bitmap from the crop rectangle
Rectangle cropRectangle = new Rectangle(min.X, min.Y, max.X - min.X, max.Y - min.Y);
Bitmap newBitmap = new Bitmap(cropRectangle.Width, cropRectangle.Height);
using (Graphics g = Graphics.FromImage(newBitmap))
{
g.DrawImage(input, 0, 0, cropRectangle, GraphicsUnit.Pixel);
}
return newBitmap;
}
Parallel.For(1, 11, (a) =>
...Parallel.For(1, 11, (e) =>
that's an instant NO. This is called over-parallelism. Most of the time it is enough if your outermost loop is the one which is parallel. \$\endgroup\$