简体   繁体   English

将位图数据提取到字节数组

[英]Extracting Bitmap Data to an array of byte

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)但是位图数据有点奇怪,我不太确定,但如果宽度为 NPOT(不是二的幂),则位图数据似乎没有正确对齐

I use following codes to construct the bmp from such bitmap data:我使用以下代码从此类位图数据构建 bmp:

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:我决定首先通过Marshal.Copy将数据复制到字节数组,然后将其复制到另一个字节数组,如果宽度为 NPOT,则跳过某个点:

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM