c# - 使用 LockBits 生成奇怪的图像

标签 c# .net image-processing gdi+ lockbits

我正在尝试使用 Lockbits 写出灰度图像,我当前的代码看起来是

/// <summary>
/// Save the content of the FrameProc out to a bitmap
/// </summary>
public void Save(string path)
{
    Bitmap bmp = new Bitmap(this.size.Width, this.size.Height
                           ,PixelFormat.Format32bppRgb);
    var data = bmp.LockBits(this.size, ImageLockMode.WriteOnly, bmp.PixelFormat);

    unsafe
    {
        for (int y = 0; y < this.size.Height; y++)
        {
            byte* row = (byte*)data.Scan0 + (y * data.Stride);
            for (int x = 0; x < this.size.Width; x++)
            {
                byte value = (byte)this.buffer[y, x];
                row[x*Bits+r] = value; 
                row[x*Bits+g] = value;
                row[x*Bits+b] = value;
            }
        }
    }

    bmp.UnlockBits(data);
    bmp.Save(path, ImageFormat.Bmp);
}

在哪里

/// <summary>
/// The amount of Bytes per pixel in the image
/// </summary>
private const int Bits = 4;

/// <summary>
/// Image components
/// </summary>
private const int a=3, r = 2, g = 1, b = 0;

但是我收到的图像不正确:

Broken image

也许这与我阅读它们的方式有关?所以这是代码

    public FrameProc(Bitmap bmp)
    {
        this.size=new Rectangle(new Point(0,0), bmp.Size);
        var data = bmp.LockBits(this.size
                               ,ImageLockMode.ReadOnly
                               ,bmp.PixelFormat);
        this.buffer = new Matrix(this.size.Height, this.size.Width);

        unsafe
        {
            for (int y = 0; y < this.size.Height; y++)
            {
                byte* row = (byte*)data.Scan0 + (y * data.Stride);
                for (int x = 0; x < this.size.Width; x++)
                {
                    this.buffer[y,x] = 0.299*row[x*Bytes+r] 
                                     + 0.587*row[x*Bytes+g] 
                                     + 0.114*row[x*Bytes+b];
                }
            }
        }

        bmp.UnlockBits(data);
    }

最佳答案

从您得到的结果来看 - 它看起来完全好像每个像素都是三个字节大而不是像您声明的那样是四个字节 - 正如人们所期望的那样。 (注意:您称它为位 - 但这是错误的 - 它应该命名为字节,而不是位)。

我会尝试其中的任何一个:

  • 从 4 个字节更改为 3 个字节
  • 从 Format32bppRgb 更改为 Format32bppArgb 并用 255 填充 alpha
  • 从 4 字节更改为 3 字节,从 Format32bppRgb 更改为 Format24bppRgb

为了性能,我也会稍微重写循环(抱歉,我无能为力):

for (int x = 0; x < this.size.Width; x++, row += Bits) 
                { 
                    byte value = (byte)this.buffer[y, x]; 
                    row[r] = value;  
                    row[g] = value; 
                    row[b] = value; 
                } 

但是,如果使用 fixed 关键字获得指向 this.buffer 的指针,您真的会获得更快的速度吗?是的,您没有遇到任何性能问题,但我忍不住要提到它!

关于c# - 使用 LockBits 生成奇怪的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7765294/

相关文章:

c# - 在 WPF 3D 中旋转 360 度

c# - 如何存储/检索 RSA 公钥/私钥

c# - 删除每种 Entity Framework 的前 10 名以外的所有内容

c++ - 正方形检测找不到正方形

python - 在OpenCV中高效地转换和混合图像

c - 如何找出图像中的直线

c# - 如何读取 MVC Controller 方法中的 web.config 设置并在 angularjs View 、 Controller 和服务中访问它们?

c# - 位图清晰度差

c# - 如何转到 Novacode Docx 中的下一页

c# - 如何使用套接字将简单消息从 WinRT 客户端(.NET 4.5)发送到桌面服务器(.NET 4.0)?