RGB 24到位图生成黑色图像

本文关键字:黑色 图像 位图 RGB | 更新日期: 2023-09-27 18:26:04

我的大脑似乎无法将图像从原始RGB颜色的byte[]转换为BitMap。我找到了一个解决方案,它允许我使用SetPixel将RGB 24bpp byte[]转换为BitMap,但我读到使用LockBits要快得多,所以我正试图找出如何用这种方式实现。

使用SetPixel方法,我使用获得一个倒置的图像

public static Bitmap CreateBitmap24bppRgb(byte[] bmpData, int width, int height)
{
    var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
    var pos = 0;
    for (var y = 0; y < height; y++)
    {
        for (var x = 0; x < width; x++)
        {
            bmp.SetPixel(x, y, Color.FromArgb(bmpData[pos], bmpData[pos + 1], bmpData[pos + 2]));
                pos += 3;
        }
    }
    return bmp;
}

我似乎不太明白如何反转。但当我尝试使用LockBits时,图像只是黑色的,我不确定自己做错了什么,这似乎很直接。

public static Bitmap CreateBitmap24bppRgb(byte[] data, int width, int height)
{
    var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
    //Create a BitmapData and Lock all pixels to be written 
    var bmpData = bmp.LockBits(
                         new Rectangle(0, 0, bmp.Width, bmp.Height),
                         ImageLockMode.WriteOnly, bmp.PixelFormat);
    //Copy the data from the byte array into BitmapData.Scan0
    for (int y = 0; y < bmp.Height - 1; y++)
    {
        Marshal.Copy(data, y * bmp.Width, bmpData.Scan0 bmpData.Stride);
    }

    //Unlock the pixels
    bmp.UnlockBits(bmpData);
    return bmp;
}

我只是好奇这里出了什么问题?

RGB 24到位图生成黑色图像

如果要创建新位图,而不是修改现有位图,则没有理由使用LockBitsMarshal.Copy

只需使用Bitmap构造函数,该构造函数将指针指向像素数据。

public static Bitmap CreateBitmap24bppRgb(byte[] data, int width, int height)
{
    GCHandle pin = GCHandle.Alloc(data, GCHandleType.Pinned);
    var bmp = new Bitmap(width, height,
                         (width * 3 + 3) / 4 * 4,
                         PixelFormat.Format24bppRgb,
                         Marshal.UnsafeAddrOfPinnedArrayElement(data, 0));
    bmp = (Bitmap)bmp.Clone(); // workaround the requirement that the memory address stay valid
                               // the clone step can also crop and/or change PixelFormat, if desired
    GCHandle.Free(pin);
    return bmp;
}

(或使用unsafe块、pinned关键字和指针)