加载原始数据转换为位图 - 我做了什么错?位图、转换为、加载、原始数据

2023-09-05 04:05:10 作者:班主任是容嬤嬤失散的孩子

我使用的是C调,.NET 4(客户端配置文件,如果这是很重要),我有一个字节数组包含图像的原始数据。具体而言,这一形象:

I'm using c sharp, .net 4 (client profile, if that's important) and I have a byte array that contains the raw data of an image. Specifically, this image:

有从理智测试后端的输出和格式上的理智网站的此处。顺便说一句,我已经过了在参数:

It is the output from the SANE test backend and the format is fully described on the SANE web site here. Incidentally, I have passed in the parameters:

在深度:8 模式:颜色

和它返回:

格式:RGB 在深度:8 行:196 每行像素:157 每行字节:471 字节流是92316字节长 format: RGB depth: 8 lines: 196 pixels per line: 157 bytes per line: 471 a byte stream that is 92316 bytes long

那么,这些数字似乎是合理的(196 *(157 * 471)= 92316) - 每像素三个字节(24位)

So, the numbers seem reasonable (196 * (157 * 471) = 92316) - three bytes (24bits) per pixel.

和从左到右,从上到下 - 像这样的(他们有一个更好的画面非常遗憾ASCIItastic方法):

And from reading the SANE documentation the data is sequenced three bytes per pixel from the top left corner going left to right, top to bottom - like this (they have a better picture sorry for this ASCIItastic approach):

red,green,blue   red,green,blue  
--------------   --------------
    byte 1           byte 2       ...

既然我这么了解我想,这将是超级simps加载它变成的位图,我敲了这一点:

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

但它产生这样的:

but it produced this:

接近,但没有雪茄,可以这么说。

close, but no cigar, so to speak.

所以,我做了什么错?

So, what have I done wrong?

推荐答案

的问题是,在一个位图有(一行的字节和下一行的字节之间的间隙更这里)。如果速度是不是你最关心的,你可以做这更容易与 SetPixel 和环

The problem is that in a bitmap there is a gap between the bytes of a line and the bytes of the next line (more here).If speed is not your primary concern, you can do this much more easily with SetPixel and a loop.

编辑: 相比于SetPixel这将使一个显著加快,但我害怕,但你还是要使用循环;)

This would give a significant speed up compared to SetPixel, but I'm afraid but you'd still have to use a loop ;)

for(int i = 0; i < bmp.Height; i++) {
    Marshal.Copy(data, 
        i * bmp.Height,
        bmpData.Scan0 + i * bmpData.Stride,
        bmp.Width * 3);
}

请注意,我没有测试code,但应该足以给你的想法。

Note that I haven't tested the code, but it should be enough to give you the idea.