Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将原始数据加载到位图-我做错了什么?_C#_.net_Image - Fatal编程技术网

C# 将原始数据加载到位图-我做错了什么?

C# 将原始数据加载到位图-我做错了什么?,c#,.net,image,C#,.net,Image,我使用的是c sharp.net 4(客户端配置文件,如果这很重要的话),我有一个字节数组,其中包含图像的原始数据。具体而言,此图像: 它是SANE测试后端的输出,其格式在SANE网站上有完整的描述。顺便说一句,我传入了以下参数: 深度:8 模式:彩色 它又回来了: 格式:RGB 深度:8 行数:196 每行像素数:157 每行字节数:471 长度为92316字节的字节流 因此,数字似乎合理(196*(157*471)=92316)-每像素3个字节(24位) 通过阅读SANE文档,数据

我使用的是c sharp.net 4(客户端配置文件,如果这很重要的话),我有一个
字节
数组,其中包含图像的原始数据。具体而言,此图像:

它是SANE测试后端的输出,其格式在SANE网站上有完整的描述。顺便说一句,我传入了以下参数:

  • 深度:8
  • 模式:彩色
它又回来了:

  • 格式:RGB
  • 深度:8
  • 行数:196
  • 每行像素数:157
  • 每行字节数:471
  • 长度为92316字节的字节流
因此,数字似乎合理(196*(157*471)=92316)-每像素3个字节(24位)

通过阅读SANE文档,数据从左上角到左到右,从上到下按每像素三个字节的顺序排列,就像这样(他们有更好的图片,很抱歉,这是一种抽象的方法):

因为我对这张图片了解得太多了,所以我想把它加载到一个文件中会是一个超级简单的过程,我想出了这个:

var bmp = new Bitmap(157, 196, PixelFormat.Format24bppRgb);
BitmapData bmpData = bmp
    .LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
              ImageLockMode.ReadWrite,
              bmp.PixelFormat);
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
bmp.UnlockBits(bmpData);
但它产生了这样的结果:

很接近,但可以说没有雪茄


那么,我做错了什么

问题在于位图中的一行字节与下一行字节之间存在间隙(更多)。如果速度不是您最关心的问题,则使用循环和循环可以更轻松地实现这一点

编辑:
与SetPixel相比,这将大大加快速度,但恐怕您仍需要使用循环;)

for(int i=0;i

请注意,我还没有测试代码,但它应该足以让您了解这一点。

位图要求将行填充到某个特定大小(4字节,searc hor格式详细信息,即)


结果是,每行157个像素并没有精确地映射到位图位的二进制格式,并且您可以看到下一行的每一行都移动了一位。我认为您需要为每行分配158*3字节,并将每行从源(由于缺少填充,不完全是位图)格式复制到目标,用0填充每行的最后3个字节。

我希望它的性能非常好-我认为图像很容易变大,所以循环和设置像素对我来说并不理想,但感谢你的建议-我会保留它,以防找不到更好的方法。太好了,谢谢-虽然使用您的信息运行它并不太有效,但我找到了自己的、非常天真的方法来运行它,它确实产生了正确的结果+1。是获得每行大小的正确方法!我查看了@BlackBear中的Stride属性,这建议(至少对我来说)我应该使用它来填充行-在本例中,步幅长度是158,因此我尝试在每行的末尾多粘贴一个0字节,它看起来是正确的
var bmp = new Bitmap(157, 196, PixelFormat.Format24bppRgb);
BitmapData bmpData = bmp
    .LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
              ImageLockMode.ReadWrite,
              bmp.PixelFormat);
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
bmp.UnlockBits(bmpData);
for(int i = 0; i < bmp.Height; i++) {
    Marshal.Copy(data, 
        i * bmp.Height,
        bmpData.Scan0 + i * bmpData.Stride,
        bmp.Width * 3);
}