5

I am trying to create a bitmap object from raw bytes, my PixelFormat is RGB with 8 bits per sample, which is 3 bytes per pixel. now for this my stide will be 3 times the width.

But Bitmap class is always looking for multiplier of 4 for stride value. Please help me how to resolve this issues. if i give multiplier of 4 image is not coming properly.

Bitmap im = new Bitmap(MyOBJ.PixelData.Columns, MyOBJ.PixelData.Rows, (MyOBJ.PixelData.Columns*3),
System.Drawing.Imaging.PixelFormat.Format24bppRgb, Marshal.UnsafeAddrOfPinnedArrayElement(images[imageIndex], 0));
user1935868
  • 95
  • 1
  • 5
  • Well, at least test it by using an image whose width is a multiple of 4 so that stride doesn't matter. Once that checks out, you'll need to fix the incompatibility by using LockBits and copying one line at a time. – Hans Passant Dec 30 '12 at 16:30
  • 1
    For a 24bit Bitmap the stride has to be a multiple of 4 byte as you have stated. So for a 24 bit bitmap the stride is stride = (((width * 3) + 3) / 4 ) * 4 you will of course have to ensure that your raw data is also formatted with any required padding at the end of each row – Dampsquid Dec 30 '12 at 16:33

1 Answers1

7

I've written a short sample which will pad every line of your array to adapt it to the required format. It will create a 2x2 check board bitmap.

byte[] bytes =
    {
        255, 255, 255,
        0, 0, 0,
        0, 0, 0,
        255, 255, 255,
    };
var columns = 2;
var rows = 2;
var stride = columns*4;
var newbytes = PadLines(bytes, rows, columns);
var im = new Bitmap(columns, rows, stride,
                    PixelFormat.Format24bppRgb, 
                    Marshal.UnsafeAddrOfPinnedArrayElement(newbytes, 0));

The PadLines method is written below. I tried to optimize it by using Buffer.BlockCopy in case your bitmaps are large.

static byte[] PadLines(byte[] bytes, int rows, int columns)
{
    //The old and new offsets could be passed through parameters,
    //but I hardcoded them here as a sample.
    var currentStride = columns*3;
    var newStride = columns*4;
    var newBytes = new byte[newStride*rows];
    for (var i = 0; i < rows; i++)
        Buffer.BlockCopy(bytes, currentStride*i, newBytes, newStride * i, currentStride);
    return newBytes;
}
e_ne
  • 8,340
  • 32
  • 43
  • @Eve i have a problem about stride i think. I used your solution but my colors does not very good. My images 8bit, 256 bppi. I changed PixelFormat to 'Format8bppIndexed'. However i couldnt manage Stride. Can you help me ? – goGud Feb 05 '14 at 08:03