应用彩色滤光片为位图对象位图、对象、彩色滤光片

2023-09-07 02:45:00 作者:妳若在 我便在

我发现这code 如何将颜色过滤器,在C#中的位图对象。它的问题是,它使用不安全的code做到这一点。是否有一个管理的,安全的方式做同样的事情?我知道我可以使用像AForge.NET或类似的库,但我希望有只适用彩色滤光片的简单方法。所有我需要的是简单的颜色更换,有黄色代替白色像素。有什么建议?

I found this code on how to apply a color filter to a Bitmap object in C#. The problem with it is it uses unsafe code to accomplish this. Is there a managed, safe way to do this same thing? I know I could use a library like AForge.NET or something similar, but I'm hoping there is a simple way to just apply a color filter. All I need is simple color replacement, replacing white pixels with yellow. Any suggestions?

推荐答案

您可以随时使用的安全GetPixel和SetPixel方法,但他们慢上许多像素使用时,这是你使用不安全的方法来使用指针的原因位图的内存。 不安全是做的方式。

You could always use the safe GetPixel and SetPixel methods, but they are slow when used on many pixels, which is the reason you use unsafe method to use pointers to the bitmap's memory. Unsafe is the way to do it.

如果你的位图是非常小的,你不关心性能所有的东西,使用与getPixel和SetPixel方法。

If your bitmap is very small and you don't care about performance all that much, use the GetPixel and SetPixel methods.

    private void ReplaceColor(Bitmap bitmap, Color originalColor, Color replacementColor)
    {
        for (var y = 0; y < bitmap.Height; y++)
        {
            for (var x = 0; x < bitmap.Width; x++)
            {
                if (bitmap.GetPixel(x, y) == originalColor)
                {
                    bitmap.SetPixel(x, y, replacementColor);
                }
            }
        }
    }

    private unsafe void ReplaceColorUnsafe(Bitmap bitmap, byte[] originalColor, byte[] replacementColor)
    {
        if (originalColor.Length != replacementColor.Length)
        {
            throw new ArgumentException("Original and Replacement arguments are in different pixel formats.");
        }

        if (originalColor.SequenceEqual(replacementColor))
        {
            return;
        }

        var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size),
                                   ImageLockMode.ReadWrite,
                                   bitmap.PixelFormat);

        var bpp = Image.GetPixelFormatSize(data.PixelFormat);

        if (originalColor.Length != bpp)
        {
            throw new ArgumentException("Original and Replacement arguments and the bitmap are in different pixel format.");
        }

        var start = (byte*)data.Scan0;
        var end = start + data.Stride;

        for (var px = start; px < end; px += bpp)
        {
            var match = true;

            for (var bit = 0; bit < bpp; bit++)
            {
                if (px[bit] != originalColor[bit])
                {
                    match = false;
                    break;
                }
            }

            if (!match)
            {
                continue;
            }

            for (var bit = 0; bit < bpp; bit++)
            {
                px[bit] = replacementColor[bit];
            }
        }

        bitmap.UnlockBits(data);
    }

用法是:

        this.ReplaceColor(myBitmap, Color.White, Color.Yellow); // SLOW

        var orgRGB = new byte[] { 255, 255, 255 }; // White (in RGB format)
        var repRGB = new byte[] { 255, 255, 0 }; // Yellow (in RGB format)

        var orgARGB = new byte[] { 255, 255, 255, 255 }; // White (in ARGB format)
        var repARGB = new byte[] { 255, 255, 255, 0 }; // Yellow (in ARGB format)

        var orgRGBA = new byte[] { 255, 255, 255, 255 }; // White (in RGBA format)
        var repRGBA = new byte[] { 255, 255, 0, 255 }; // Yellow (in RGBA format)

        var orgBytes = orgRGB; // or ARGB or RGBA, depending on bitmap's pixel format
        var repBytes = repRGB; // or ARGB or RGBA, depending on bitmap's pixel format

        this.ReplaceColorUnsafe(myBitmap, orgBytes, repBytes); // FAST