我一直在尝试使用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图像。我做错了什么?
答案 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);
}
结果,显示在我的测试程序中: