Byte数组移位的位图

时间:2014-05-25 13:26:45

标签: c# bitmap streaming byte marshalling

我正在尝试使用以下代码从字节数组创建Bitmap:

var b = new Bitmap(pervoe, vtoroe, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
ColorPalette ncp = b.Palette;
for (int i = 0; i < 256; i++)
    ncp.Entries[i] = System.Drawing.Color.FromArgb(255, i, i, i);

b.Palette = ncp;

var BoundsRect = new Rectangle(0, 0, Width, Height);

BitmapData bmpData = b.LockBits(BoundsRect,ImageLockMode.WriteOnly,b.PixelFormat);

IntPtr ptr = bmpData.Scan0;

int bytes = (bmpData.Stride)*(b.Height);
        var rgbValues = new byte[bytes];
// filling values

Marshal.Copy(rgbValues, 0, ptr, bytes);

b.UnlockBits(bmpData);
        return b;   

问题在于,当我得到输出图像时,从第一行开始的每一行都向右移动,因此整个图像看起来不正确。 问题不在于rgbValues - 我试图将它与setPixel方法一起使用,它完美无缺。 任何关于元帅课程的帮助,或者我该如何防止这种转变?

1 个答案:

答案 0 :(得分:1)

您展示的代码看起来很好,应该按预期工作。问题很可能与您实施// filling values部分的方式有关。我的猜测是,您的图片宽度为bmpData.Stride != b.Width(因此bytes != Width * Height),但您没有考虑它并填充Width * Height的第一个rgbValues字节阵列。

出于优化目的,Bitmap实现可以选择向图像数据的每一行添加填充字节,这些图像数据实际上不是图像的一部分。如果它这样做,你应该考虑到这一点并将你的图像数据写入每行的第一个Width字节,其中每一行从索引rowIndex * BitmapData.Stride开始。

因此,您应该按照以下方式填充缓冲区:

for (int row = 0; row < b.Height; ++row)
{
    int rowStart = row * bmpData.Stride;
    for (int column = 0; column < b.Width; ++column)
    {
        rgbValues[rowStart + column] = GetColorForPixel(column, row);
    }
}