1

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?

1 Answer 1

2

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();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.