将字节从Bitmap复制到字节数组并使用Marshall.Copy返回不起作用

时间:2017-01-03 13:44:42

标签: c# bitmap marshalling

我想用Marshall.Copy复制字节。我的代码工作,但字节对我来说很奇怪。我想,我的索引不是真正的字节。如果这个计算并保存回来,我在图像中得到了不同的颜色,字节大小更大(图像大小相同)。

 Bitmap bmp = new Bitmap(imagepath);
    Width = bmp.Width;
    Height = bmp.Height;
    byte[] data;
    BitmapData bdata;
    switch (bmp.PixelFormat)
    {
      case PixelFormat.Format8bppIndexed:
      {
        data = new byte[Width * Height];
        bdata = bmp.LockBits(new Rectangle(0, 0, Width, Height),ImageLockMode.ReadOnly, bmp.PixelFormat);
        Marshal.Copy(bdata.Scan0, data, 0, data.Length);
        bmp.UnlockBits(bdata);
        break;
      }
    }

从字节保存图像:

BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
IntPtr pNative = bmData.Scan0;
Marshal.Copy(data, 0, pNative, Width * Height);
bmp.UnlockBits(bmData);
bmp.Save("output.gif",ImageFormat.Gif); //without format, have same problem

如果我从第一个像素读取颜色,我得到:Color [A=0, R=0, G=0, B=2]。这是输入图像中的真彩色吗?

我不知道为什么输出与输入不同。哪里有问题?

输入和输出示例(抱歉小图片): Input Output

1 个答案:

答案 0 :(得分:1)

您没有显示如何创建第二个bmp来重新加载字节。但PixelFormat8bbpIndexed,这意味着您的data数组将包含调色板索引而不是直接颜色信息。当您使用8位像素格式创建第二个bmp时,它将使用默认调色板,该调色板可能与原始调色板不同。

因此,您必须保存第一张图片的bmp.Palette,然后使用它来恢复第二张bmp实例的实际颜色。

更新:虽然您可以逐个设置调色板条目,但它无效。您必须改为设置整个调色板。此外,here是一个带有索引位图操作的帖子(请参阅ConvertPixelFormat)方法。