Reputation: 23
I'm trying to create Bitmap from byte array using this code:
var b = new Bitmap(pervoe, vtoroe, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
ColorPalette ncp = b.Palette;
for (int i = 0; i < 256; i++)
ncp.Entries[i] = System.Drawing.Color.FromArgb(255, i, i, i);
b.Palette = ncp;
var BoundsRect = new Rectangle(0, 0, Width, Height);
BitmapData bmpData = b.LockBits(BoundsRect,ImageLockMode.WriteOnly,b.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = (bmpData.Stride)*(b.Height);
var rgbValues = new byte[bytes];
// filling values
Marshal.Copy(rgbValues, 0, ptr, bytes);
b.UnlockBits(bmpData);
return b;
the problem is that when I get the output image each row starting from the first is shifted to the right so the whole image doesnt look right . The problem is not in the rgbValues - I've tried to use it with setPixel method and it works perfectly. Any help with marshal class or what do I do to prevent that shifting?
Upvotes: 2
Views: 765
Reputation: 4183
The code you are showing looks fine and should work as intended. The problem is most likely related to how you've implemented the // filling values
part. My guess is that the width of your image is such that bmpData.Stride != b.Width
(and thus bytes != Width * Height
) but you do not account for it and fill the first Width * Height
bytes of the rgbValues
array.
For optimilization purposes, the Bitmap
implementation may choose to add padding bytes to each row of image data that are not actually part of the image. If it does so, you should account for this and write your image data to the first Width
bytes of each row, where each rows starts at index rowIndex * BitmapData.Stride
.
You should thus fill your buffer along the lines of:
for (int row = 0; row < b.Height; ++row)
{
int rowStart = row * bmpData.Stride;
for (int column = 0; column < b.Width; ++column)
{
rgbValues[rowStart + column] = GetColorForPixel(column, row);
}
}
Upvotes: 3