在 C# 中修改像素的最快方法是什么

What is the fastest way to modify pixels in C#

我想将位图中的指定像素更改为透明。 方法如下:

        Bitmap bt = new Bitmap(Mybitmap);
        System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, Mybitmap.Width, Mybitmap.Height);
        BitmapData bmpdata = bt.LockBits(rect, ImageLockMode.ReadWrite, bt.PixelFormat);
        IntPtr ptr = bmpdata.Scan0;
        int bytes = Math.Abs(bmpdata.Stride) * bt.Height;
        byte[] rgbValues = new byte[bytes];
        Marshal.Copy(ptr, rgbValues, 0, bytes);
        int len = rgbValues.Length;

        for (int i = 0; i < len; i += 4)
        {
            //Some colors are already stored in this SpecificColor1ist, and pixels with the same color will be changed to transparent
            foreach (var item in SpecificColor1ist)
            {
                
                if ((rgbValues[i]==item.B)&&(rgbValues[i+1] == item.G)&&(rgbValues[i+2] == item.R))
                {
                    rgbValues[i + 3] = (byte)0;
                }
            }

        }
        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
        bt.UnlockBits(bmpdata);
        return bt;

但是速度太慢了。有什么办法让它更快吗?不安全的代码也是可以接受的。

  1. 你有一个指向像素数据数组的指针,为什么不使用它Scan0(你需要将你的方法设置为不安全的,并在项目的构建选项中适当地设置它)
  2. 您可以确保您的像素格式是 32 位。
  3. 您可以使用 int
  4. 一次性比较您的 rbg 值
  5. 使用 HashSet 进行更快的查找
  6. 使用 按位 &
  7. 清除 apha-channel

例子

var colorHash = SpecificColor1ist
   .Select(x => x.ToArgb())
   .ToHashSet();

...

var data = bt.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);


var length = (int*)data.Scan0 + Mybitmap.Height * Mybitmap.Width;
for (var p = (int*)data.Scan0; p < length; p++)
   if(colorHash .Contains(*p))
      *p = (*p & 0xFFFFFF) // i think sets the alpha to 0

...