C# 用字节数组填充picxturebox会产生奇怪的效果

C# 用字节数组填充picxturebox会产生奇怪的效果,c#,arrays,C#,Arrays,我正在用c#写,并用它来填充我的图片盒 var bmp = new Bitmap(48, 32, PixelFormat.Format1bppIndexed); var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat); Marshal.Copy(fileArray, 0,

我正在用c#写,并用它来填充我的
图片盒

var bmp = new Bitmap(48, 32, PixelFormat.Format1bppIndexed);
var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                           ImageLockMode.WriteOnly, bmp.PixelFormat);

Marshal.Copy(fileArray, 0, bmpData.Scan0, fileArray.Length);
bmp.UnlockBits(bmpData);

return bmp;
结果很奇怪

它最多只填充第125个字节。所以我试着处理数据,0-125字节按它们应该显示的那样显示,但字节125之后的任何内容都不会显示,它会覆盖字节125


所以,如果我做0-125 all
0xff
,我会得到顶部的实心条。但是将126添加为
0x00
它将125替换为
0x00

这个解决方案对我很有效。到目前为止,它还不是最好的,显示出缺乏理解,或者仅仅是位图不能支持每像素1位的单色图像。它永远不会停止工作。所有这些都是在每行6个字节上添加2个字节。这样迈步就可以应付了

int j = 1;
int k = 0;
for (int i = 0; i < 192; i++)
{
    fixArray[k] = blob[i];
    j++;
    if (j == 7)
    {
        j = 1;
        fixArray[++k] = 0;
        fixArray[++k] = 0;
    }
    k++;
}
intj=1;
int k=0;
对于(int i=0;i<192;i++)
{
fixArray[k]=blob[i];
j++;
如果(j==7)
{
j=1;
固定数组[++k]=0;
固定数组[++k]=0;
}
k++;
}

您可以逐行移动数据,而不是在数据中插入填充:

int w = 48;
int h = 32;
int unpadded = w / 8;   // unpadded byte length of one line in your data

Bitmap bmp = new Bitmap(w, h,  PixelFormat.Format1bppIndexed);
BitmapData bmpData = bmp.LockBits(
                        new Rectangle(0, 0, bmp.Width, bmp.Height),
                        ImageLockMode.WriteOnly, bmp.PixelFormat);

int stride = 8 // padded length of scanline

for (int i = 0; i < h; i++)
{
    Marshal.Copy(blob, i * unpadded , bmpData.Scan0 + i * stride, unpadded );  
}
bmp.UnlockBits(bmpData);
return bmp;
intw=48;
int h=32;
int unpadded=w/8;//未添加数据中一行的字节长度
位图bmp=新位图(w、h、PixelFormat.Format1BPindexed);
BitmapData bmpData=bmp.LockBits(
新矩形(0,0,bmp.Width,bmp.Height),
ImageLockMode.WriteOnly,bmp.PixelFormat);
int stride=8//扫描线的填充长度
对于(int i=0;i
请注意,要使位图操作更快,所有物理行的长度必须是4字节的倍数。由此产生的填充长度称为

跨距是一行像素(扫描线)的宽度, 四舍五入到四字节边界。如果步幅为正值,则 位图是自顶向下的。如果步幅为负数,则位图为负数 自下而上

逻辑长度为48像素,1bpp,逻辑长度为6字节,因此必须在内部填充到8字节

最好不要在托管代码中移动数据来准备,而是只将正确的部分移动到正确的插槽


这里有更多的

无法重现问题。我用所有256个可能的值(随机生成)填充位图。我还将调色板更改为黄色/红色,以确定最终的工件,但没有出现任何问题。生成的位图可以指定给PictureBox图像属性或在其上绘制。您正在用字节数组填充位图数据(
Marshal.Copy(…)
),从
BitmapData.Scan0
指向的地址开始。数组的大小为
[BitmapData.Stride*Bitmap.Height]
。如果您查看
步幅
,它会说它的大小是
8
。总共(8*32)256字节。您无法设置跨距,只需使用它来调整阵列大小。我不明白你为什么总是引用
6
的值。您不必确定位图扫描线的大小。计算时需要使用这些信息。步长是位图表示一行像素所需的字节数。不是原始的
[Bitmap.Width/8]
。你不必在意它。只需使用此度量来调整阵列的大小。(只有8个字节,因为您的
PixelFormat
format1bpappindexed
,索引调色板为2种颜色)。顺便问一下,你的数组的内容是什么?只有索引颜色,对吗?
format1bpindexed
可以表示任何颜色,但调色板只有两种颜色。黑色和白色是两个可能的值。重建源取决于数组中的数据来自何处。顺便说一句,BitmapData步长(表示扫描线所需的字节数)始终是4的倍数,因为为了硬件兼容性,它与4个字节对齐。Taw,喜欢它。非常好的教育!