Bitmap.MakeTransparent()太慢

问题描述 投票:1回答:1

我将黑白图片用作蒙版,以在应用矩形后生成漂亮的轮廓。不幸的是,要消除黑色,我使用了MakeTransparent方法,但是很慢,在我的代码中我必须执行两次这样的过程,在20张图像的情况下,大约需要5秒钟。还有其他解决方案可以加快此过程吗?

Bitmap contour = new Bitmap(
    imageMaskCountour.Width, imageMaskCountour.Height, PixelFormat.Format32bppArgb);

using (Graphics g = Graphics.FromImage(contour))
{
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
    g.FillRectangle(ContourBrush, 0, 0, contour.Width, contour.Height);
    g.DrawImage(
        imageMaskCountour,
        new Rectangle(0, 0, contour.Width, contour.Height),
        new Rectangle(0, 0, imageMaskCountour.Width, imageMaskCountour.Height),
        GraphicsUnit.Pixel);
}

contour.MakeTransparent(Color.Black);

编辑:

我尝试添加LockBitmap并添加以下方法:

public void MakeTransparent(Color color)
{
    for (int y = 0; y < this.Height; y++)
    {
        for (int x = 0; x < this.Width; x++)
        {
            if (this.GetPixel(x, y) == color)
            {
                this.SetPixel(x, y, Color.Transparent);
            }
        }
    }
}

但是速度慢很多。

c# algorithm optimization drawing
1个回答
1
投票

您对位图所做的每个操作都需要锁定和解锁位。这使其非常缓慢。请参阅this answer如何通过一次锁定,操作所有数据并最终将其解锁直接访问位图数据。

以下代码是使用刚刚提到的直接访问的常规Bitmap的扩展方法。它实现了方法的逻辑。请注意,我将HeightWidth保存到局部变量。我这样做是因为我认识到像在循环条件下那样多次使用它也很慢。

public static void FastMakeTransparent(this Bitmap bitmap, Color color)
{
    BitmapData bitmapData = bitmap.LockBits(
        new Rectangle(0, 0, bitmap.Width, bitmap.Height),
        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

    unsafe
    {
        int* pixelPointer = (int*)bitmapData.Scan0;

        int bitmapHeight = bitmap.Height;
        int bitmapWidth = bitmap.Width;
        int colorInt = color.ToArgb();
        int transparentInt = Color.Transparent.ToArgb();

        for (int i = 0; i < bitmapHeight; ++i)
        {
            for (int j = 0; j < bitmapWidth; ++j)
            {
                if (*pixelPointer == colorInt)
                    *pixelPointer = transparentInt;
                ++pixelPointer;
            }
        }
    }

    bitmap.UnlockBits(bitmapData);
}

在我的Intel Core2Duo P8400(2.26 GHz)CPU上具有Stopwatch类的基准。

Bitmap size 1000x1000 random filled accumulated time of 100 runs
Target AnyCPU .NetFramework 4.5.2

Release build

MakeTransparent      Ticks: 24224801 | Time: 2422 ms
FastMakeTransparent  Ticks: 1332730  | Time: 133 ms


Debug build

MakeTransparent      Ticks: 24681178 | Time: 2468 ms
FastMakeTransparent  Ticks: 5976810  | Time: 597 ms
热门问题
推荐问题
最新问题