C#-使图像的黑色像素透明

时间:2018-10-06 18:57:54

标签: c# image pixel

我有一个大问题。

我有一个代码可以比较2个图像像素。它在第二个图像像素内寻找第一个图像像素。

 private bool FindBitmap12(Bitmap bmpNeedle, Bitmap bmpHaystack, out Point location)
    {
        if (bmpNeedle == null || bmpHaystack == null)
        {
            location = new Point();
            return false;
        }
        for (int outerX = 0; outerX < bmpHaystack.Width - bmpNeedle.Width; outerX++)
        {
            for (int outerY = 0; outerY < bmpHaystack.Height - bmpNeedle.Height; outerY++)
            {
                for (int innerX = 0; innerX < bmpNeedle.Width; innerX++)
                {
                    for (int innerY = 0; innerY < bmpNeedle.Height; innerY++)
                    {
                        Color cNeedle = bmpNeedle.GetPixel(innerX, innerY);
                        Color cHaystack = bmpHaystack.GetPixel(innerX + outerX, innerY + outerY);
                        if (cNeedle.R != cHaystack.R || cNeedle.G != cHaystack.G || cNeedle.B != cHaystack.B)
                        {
                            goto notFound;
                        }
                    }
                }
                location = new Point(outerX, outerY);
                return true;
            notFound:
                continue;
            }
        }
        location = Point.Empty;
        return false;
    }

上面的代码很完美。

问题是,现在我需要比较上面有黑色像素的图片和没有黑色像素的图片。那么发生的是上面的代码返回的图片是不同的。

所以我想:嘿,让这个黑色像素透明!

我输入了以下代码:

Rectangle mouseNewRect = new Rectangle(new Point(x - 125, y - 125), new Size(250, 250));
Bitmap myBitmap2 = new Bitmap(mouseNewRect.Width, mouseNewRect.Height);
Bitmap myBitmap3 = new Bitmap("Images\\xd1.png");
myBitmap3.MakeTransparent(Color.Black);
Graphics g = Graphics.FromImage(myBitmap2);
g.CopyFromScreen(mouseNewRect.Left, mouseNewRect.Top, 0, 0, myBitmap2.Size, CopyPixelOperation.SourceCopy);

myBitmap2 ==大图;

myBitmap3 ==图片将具有在myBitmap2中进行比较的黑色像素。

正如你们所看到的,我将myBitmap3黑色像素设为透明,因此,当将myBitmap3与myBitmap2比较时,结果应该是:嘿,我们在myBitmap2内部发现了myBitmap3的像素!

我不知道为什么,但是即使使黑色像素透明,也会导致:

bool sucess2 = FindBitmap12(myBitmap3, myBitmap2, out location);

==否。因此,我使黑色像素透明,但是以某种方式,成功2 ==假。

我尝试删除https://pixlr.com上的黑色像素,在此黑色像素中留有“空白”空间,但也有sucess2 == false的结果。

Some1对如何删除myBitmap3的黑色像素有任何想法吗?

谢谢。

编辑:在这一部分:

Color cNeedle = bmpNeedle.GetPixel(innerX, innerY);
Color cHaystack = bmpHaystack.GetPixel(innerX + outerX, innerY + outerY);
if (cNeedle.R != cHaystack.R || cNeedle.G != cHaystack.G || cNeedle.B != cHaystack.B)
                        {
                            goto notFound;
                        }

也许我可以做一个“如果”,如果找到一个黑色像素,则忽略它并继续搜索,因为这个黑色像素不存在?

1 个答案:

答案 0 :(得分:-1)

在不深入into the API的情况下,我假设MakeTransparent方法不会更改像素的RGB值。它只是在调色板和信息中的某处设置了该特定颜色,不应在屏幕上绘制。这就是为什么当您比较RGB值时它们仍然相同的原因。

我没有测试或验证我的答案,但这是我假设使用图像一段时间。

如果我是对的,最简单的方法可能是只比较未在调色板中标记为透明颜色的像素。

更新

似乎不是检查系统选板的简单方法。参见https://docs.microsoft.com/en-us/windows/desktop/gdi/system-palette

相反:您能否尝试比较像素的alpha分量?如果您已将像素的Alpha值(通过pixlr / gimp / photoshop)设置为透明,则其值应为0。因此您的代码应为:

Color cNeedle = bmpNeedle.GetPixel(innerX, innerY);
Color cHaystack = bmpHaystack.GetPixel(innerX + outerX, innerY + outerY);

bool isDifferentRGB = cNeedle.R != cHaystack.R || cNeedle.G != cHaystack.G || cNeedle.B != cHaystack.B;
bool isTransparent = cNeedle.A == 0;

if (isDifferentRGB && !isTransparent)
{
     goto notFound;
}