I have the below working code to create a Bitmap from the source pixels array. The source array is of type byte[ ] and it's the output of a library function and it is a flatten array 3D => 1D.
My code to create the Bitmap:
var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
// unflattening 1D array using 3D coordinates
// index = z * yMax * xMax + y * xMax + x
var rv = pixels[0 * height * width + j * width + i];
var gv = pixels[1 * height * width + j * width + i];
var bv = pixels[2 * height * width + j * width + i];
bmp.SetPixel(i, j, Color.FromArgb(rv, gv, bv));
}
}
The above code works, but it is slow. For a 2048 x 1364 bitmap it takes about 2 seconds to create. I checked stackoverflow for similar cases, there are solutions using BitmapData and Marshal.Copy but those are the cases when source array is not a 3D=>1D flattened array. Of course I tried to use BitmapData and copy from pixels to BitmapData.Scan0 but got a wrong bitmap. Is there any trick, how to speedup the bitmap creation?
Update: Based on comments below I ended up with this code, which works much faster:
var bytes = new byte[pixels.Length];
var idx = 0L;
var area = height * width;
var area2 = 2 * area;
var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
var bmd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
var Unflatten1D = j * width + i;
bytes[idx] = pixels[Unflatten1D];
bytes[idx + 1] = pixels[Unflatten1D + area];
bytes[idx + 2] = pixels[Unflatten1D + area2];
idx += 3;
}
}
Marshal.Copy(bytes, 0, bmd.Scan0, bytes.Length);
bmp.UnlockBits(bmd);