Let's say, I have an array of byte containing raw bitmap data without headers.
However the bitmap data is a bit weird, I'm not quite sure but it seems the bitmap data is not correctly aligned if the width is NPOT (Not Power of Two)
I use following codes to construct the bmp from such bitmap data:
public Bitmap GetBitmap(byte[] bitmapData, int width, int height)
{
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format16bppRgb555);
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
unsafe
{
byte* ptr = (byte*)bmpData.Scan0;
for (int i = 0; i < bitmapData.Length; i++)
{
*ptr = bitmapData[i];
ptr++;
if (width % 2 != 0)
{
if ((i + 1) % (width * 2) == 0 && (i + 1) * 2 % width < width - 1)
{
ptr += 2;
}
}
}
}
bitmap.UnlockBits(bmpData);
return bitmap;
}
The code works fine so far. But for some reasons, I need to implement "Import Bitmap", which mean I need to get the "weird" bitmap data from an instance of bitmap.
How do I do this?
Finally, I figure out how to do this.
I decide to copy the data first to an array of byte via Marshal.Copy
and then copy it to another array of bytes while skip some point if the width is NPOT (Non-Power-Of-Two):
public byte[] ImportBitmap(Bitmap bitmap)
{
int width = bitmap.Width, height = bitmap.Height;
var bmpArea = new Rectangle(0, 0, width, height);
var bmpData = bitmap.LockBits(bmpArea, ImageLockMode.ReadWrite, PixelFormat.Format16bppRgb555);
var data = new byte[bmpData.Stride * height];
Marshal.Copy(bmpData.Scan0, data, 0, data.Length);
bitmap.UnlockBits(bmpData);
bitmap.Dispose(); // bitmap is no longer required
var destination = new List<byte>();
int leapPoint = width * 2;
for (int i = 0; i < data.Length; i++)
{
if (width % 2 != 0)
{
// Skip at some point
if (i == leapPoint)
{
// Skip 2 bytes since it's 16 bit pixel
i += 1;
leapPoint += (width * 2) + 2;
continue;
}
}
destination.Add(data[i]);
}
return destination.ToArray();
}