在C#中用RGB数组创建位图,结果图像差异?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C#中用RGB数组创建位图,结果图像差异?相关的知识,希望对你有一定的参考价值。

我正在使用类似于this answer的方法从字节数组创建位图。

private static void MySaveBMP(byte[] buffer, int width, int height)
{
    Bitmap b = new Bitmap(width, height, PixelFormat.Format24bppRgb);
    Rectangle BoundsRect = new Rectangle(0, 0, width, height);
    BitmapData bmpData = b.LockBits(BoundsRect,
                                    ImageLockMode.WriteOnly,
                                    b.PixelFormat);
    IntPtr ptr = bmpData.Scan0;

    // fill in rgbValues
    Marshal.Copy(buffer, 0, ptr, buffer.Length);
    b.UnlockBits(bmpData);
    b.Save(@"D:myPic.bmp", ImageFormat.Bmp);        
}

我生成一个字节数组,填写一些像这样的值:

int width = 20;
int height = 30;
int bytesPerPixel = 3;
int bytesPerRow = width * bytesPerPixel;
int totalLength = bytesPerRow * height;            
byte[] managedArray = new byte[totalLength];

// fill background with white
for (int i = 0; i < totalLength; i++)
    managedArray[i] = 255;

// draw on each row
for (int i = 0; i < height; i++)
{
    // first pixel is green
    managedArray[0 + i * bytesPerRow] = 0;
    managedArray[1 + i * bytesPerRow] = 255;
    managedArray[2 + i * bytesPerRow] = 0;
    // last pixel is red
    managedArray[bytesPerRow - 3 + i * bytesPerRow] = 0;
    managedArray[bytesPerRow - 2 + i * bytesPerRow] = 0;
    managedArray[bytesPerRow - 1 + i * bytesPerRow] = 255;
}
MySaveBMP(managedArray, width, height);

生成的20x30 bmp图像如下所示:

20x30 bmp image

但是,如果我更改图像高度(例如,更改为21),则生成的图像似乎已损坏。每一行看起来都向左移动了一下:

21x30 bmp image

制作位图图像时我做错了什么?

答案

我想我找到了答案。因为我没有意识到BitmapData.Stride的属性。有人有答案here.

我修改过的保存功能在这里:

    private static void MySaveBMP(byte[] buffer, int width, int height)
    {
        Bitmap b = new Bitmap(width, height, PixelFormat.Format24bppRgb);

        Rectangle BoundsRect = new Rectangle(0, 0, width, height);
        BitmapData bmpData = b.LockBits(BoundsRect,
                                        ImageLockMode.WriteOnly,
                                        b.PixelFormat);

        IntPtr ptr = bmpData.Scan0;

        // add back dummy bytes between lines, make each line be a multiple of 4 bytes
        int skipByte = bmpData.Stride - width*3;
        byte[] newBuff = new byte[buffer.Length + skipByte*height];
        for (int j = 0; j < height; j++)
        {
            Buffer.BlockCopy(buffer, j * width * 3, newBuff, j * (width * 3 + skipByte), width * 3);
        }

        // fill in rgbValues
        Marshal.Copy(newBuff, 0, ptr, newBuff.Length);
        b.UnlockBits(bmpData);
        b.Save(@"D:myPic.bmp", ImageFormat.Bmp);        
    }

另一个解决方案是,我将PixelFormat更改为Format32bppPArgb,并将bytesPerPixel更改为4.所以我不需要打扰4字节扫描线格式。

以上是关于在C#中用RGB数组创建位图,结果图像差异?的主要内容,如果未能解决你的问题,请参考以下文章

c/c++ 将 RGBQUAD 数组分配给位图

numpy中数组之间的区别

当我将我的 rgb 位图转换为 yuv 时,它会产生红色图像。我想以 YUV 格式从图库中读取图像或将 RGB 位图转换为 YUV

69 RGB图像转单色位图

69 RGB图像转单色位图

69 RGB图像转单色位图