Byte数组用于位图的像素格式

时间:2018-05-17 03:30:26

标签: c# arrays bitmap

我一直在尝试使用c#将简单的字节数组放入图片框中。我试过的大多数例子都给我参数无效。如果我不使用使用或转换器并将其分解出来(请参阅下面的代码),我会得到一张图片,但看起来不对(全黑,上面有一些随机的彩色圆点)。

 Bitmap bmp = new Bitmap(48, 32, PixelFormat.Format24bppRgb);
            BitmapData bmpData = bmp.LockBits(
                                 new Rectangle(0, 0, bmp.Width, bmp.Height),
                                 ImageLockMode.WriteOnly, bmp.PixelFormat);
            Marshal.Copy(blob, 0, bmpData.Scan0, blob.Length);
            bmp.UnlockBits(bmpData);
            return bmp;

字节数组看起来像这样。

01 c7 f0 70 3f 03 00 c3 f0 60 1e 01 80 63 ff c3 1c 71 88 21 ff c7 3c f3 8e 31 f0 c7 fc ff 86 31 f0 c7 fc ff c4 31 f0 c1 fc 3f c0 31 e0 e0 7e 0f c0 f1 e1 f8 3f 83 c0 31 e1 fe 1f e1 c6 31 e0 ff 9f f9 86 30 f0 fb 9c 79 8f 38 f0 e3 98 79 8f 38 f8 63 98 79 80 30 38 62 1c 61 80 70 10 70 3e 03 ff ff ff ff ff ff ff ff ff ff ff ff ff 00 7e 00 78 7f f0 88 3c 18 18 3f f0 8e 3c 7e 0f 0f c3 86 30 ff 07 87 87 c4 31 ff 87 e0 8f c0 71 ff e7 f8 0f c0 71 ff e7 f0 0f c0 71 ff e7 f0 0f c6 71 ff e7 f0 1f 86 10 ff 87 e1 1f 8f 18 ff 8f 87 87 8f 18 7f 0f 0f c3 80 1c 0c 18 3f f0 80 7e 00 38 7f f0

我的图像应该是192个字节和48 x 32 res图像。我做错了什么?

1 个答案:

答案 0 :(得分:1)

Michael Liu所述,如果您的数据是192个字节,并且您需要从中获取32行数据,那么每行将是6个字节,这意味着从这样的行中获得48个像素,你需要将它乘以8,换句话说,每像素使用1位,即PixelFormat.Format1bppIndexed

至于您在数据可视化方面的问题,您需要考虑stride;每行像素的实际字节数。

由.Net框架always use a multiple of four bytes as width of each line of pixels创建的图像,因此您制作的新48x32图像每行将有8个字节。但是,您的图像数据是完全紧凑的数据,因此每行只有6个字节。

因此,您需要逐行复制,同时考虑输入和输出的步幅。这意味着您应该在每行Marshal.Copy的高度上用循环替换单个Marshal.Copy,将每6个字节的数据从输入数组复制到输出中每行的正确开始指针

调整后的Marshal.Copy操作应该是这样的:

Int32 newDataWidth = ((Image.GetPixelFormatSize(pixelFormat) * width) + 7) / 8;
Int32 targetStride = bmpData.Stride;
Int64 scan0 = bmpData.Scan0.ToInt64();
for (Int32 y = 0; y < height; y++)
    Marshal.Copy(blob, y * stride, new IntPtr(scan0 + y * targetStride), newDataWidth);

...使用stride输入数组的步幅(在本例中为6)。

要自动输入步幅计算,如果您知道您拥有完全紧凑的数据,则可以使用我在上一个块中显示的公式:

public static Int32 GetMinimumStride(Int32 width, Int32 bitsLength)
{
    return ((bitsLength * width) + 7) / 8;
}

我已经在SO to build an image from bytes in any format上发布了代码,所以你可以使用它,我想。使用BuildImage函数,您可以像这样构建图像:

public static Bitmap BuildMonoBitmap(Byte monoBytes, Int32 width, Int32 height)
{
    Color[] pal = new Color[] {Color.Black, Color.White};
    Int32 stride = GetMinimumStride(width, 1);
    return BuildImage(monoBytes, width, height, stride, PixelFormat.Format1bppIndexed, pal, null);
}

结果,显示在我的测试程序中:

Bliss Box