1

I'm trying to create a bitmap from separate Red, Green, and blue arrays so I can use this bitmap later to create a frame for an avi file (SharpAVI). I've tried the following code which works:

Bitmap Bmp = new Bitmap(Width, Height);   
for (int ii = 0; ii < (Width*Height); ii++)
{
    ypos = ii / Width;
    xpos = ii % Width;
    Bmp.SetPixel(xpos, ypos, Color.FromArgb(dataR[ii], dataG[ii], dataB[ii]));
}

the arrays dataR, dataG, and dataB contain the values (0 to 255) of the colors starting from 0,0 and ending on width,height. However, this code is rather slow. I would prefer to directly produce the bitmap from the data, but I'm not sure how. I've seached around and found something in the direction of:

Bitmap bm_Image = new Bitmap(Width, Height, Stride, PixelFormat.Format24bppRgb, ipPtrRGB);

but I don't fully understand how this works. I've read something about padding the data etc. Does anybody know a method to do this fast?

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
MrEighteen
  • 434
  • 4
  • 16
  • See [here](http://stackoverflow.com/questions/28792723/adding-or-subtracting-color-from-an-image-in-a-picturebox-using-c-sharp/28799612?s=9|0.3049#28799612) for an example of using lockbits. – TaW Jun 28 '15 at 17:29

1 Answers1

1

If you want to work with bitmaps faster, I would suggest using this LockBitmap class, found here: http://www.codeproject.com/Tips/240428/Work-with-bitmap-faster-with-Csharp

The implementation is relatively simple, and you can use the same data structures that you are using at the moment. This is what the LockBitmap implementation will look like for your code:

Bitmap Bmp = new Bitmap(Width, Height);
LockBitmap lockBitmap = new LockBitmap(Bmp);
lockBitmap.LockBits();
for (int ii = 0; ii < (Width*Height); ii++)
{
    ypos = ii / Width;
    xpos = ii % Width;    
    lockBitmap.SetPixel(xpos, ypos, Color.FromArgb(dataR[ii], dataG[ii], dataB[ii]));
}
lockBitmap.UnlockBits();
Bmp.Save(filename)

I've used this class myself for a few projects, and I found it to be much faster than the standard .NET functions. The link above even has a benchmark test you can run to see how much faster it is.

Eoin
  • 833
  • 2
  • 13
  • 24
  • The `SetPixel` I'm using in the example is actually a function of the `LockBitmap` class in the link - it's not the same as `Bitmap.SetPixel` at all, it just has the same name! – Eoin Jun 28 '15 at 17:30
  • Ah, interesting. so it is an alternative to setting the channels directly. (Nice avatar btw ;-) - I don't think the division is a good idea though! – TaW Jun 28 '15 at 17:36
  • 1
    That works like a charm, thank you very much! Where my previous code used 250ms to store a 800x500 picture, it now uses only around 50ms. @TaW why do you think the division is a bad idea? I thought it was an easy way to get the right index for the x and y positions. – MrEighteen Jun 28 '15 at 19:07
  • The usualy way is to use a double loop with only additions in it. But the (by far) bigger gain over integer division is using lockbits.. – TaW Jun 28 '15 at 19:28