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

标签 c# .net image

我使用的是 c sharp、.net 4(客户端配置文件,如果这很重要的话)并且我有一个包含图像原始数据的 byte 数组。具体来说,这张图片:

good image

它是 SANE 测试后端的输出,SANE 网站上对格式进行了完整描述 here .顺便说一句,我传入了参数:

  • 深度:8
  • 模式:颜色

它已经返回:

  • 格式:RGB
  • 深度:8
  • 行数:196
  • 每行像素:157
  • 每行字节数:471
  • 一个长度为 92316 字节的字节流

因此,这些数字看起来很合理 (196 * (157 * 471) = 92316) - 每个像素三个字节(24 位)。

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

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

因为我对图像了解得太多了,所以我认为将它加载到 Bitmap 中会非常简单。我敲了这个:

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

但它产生了这个:

bad image

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

那么,我做错了什么?

最佳答案

问题是在位图中,一行的字节和下一行的字节之间存在间隙(更多 here )。如果速度不是您最关心的问题,您可以更轻松地做到这一点SetPixel和一个循环。

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

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

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

关于c# - 将原始数据加载到位图中 - 我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15254990/

相关文章:

java - 如何在 java webapp 中的服务器上保存和检索图像

.net - 以编程方式在 Excel 中删除 "The number in this cell is formatted as text or preceded by an apostrophe"

css - Twitter Bootstrap 图像居中与叠加

c# - .NET 私​​钥 Rsa 加密

c# - 如何获得使用类变量的方法调用

.net - 适用于 Mac 的 VSTO?

c# - 为什么要使用 Hashtable.Synchronized?

image - 如何在 MATLAB 中将图像变形为梯形

c# - 没有类型为 'IEnumerable<SelectListItem>' 且键为 '......' 的 ViewData 项

c# - 如何将变量定义为 lambda 函数