我有一个大问题。
我有一个代码可以比较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;
}
也许我可以做一个“如果”,如果找到一个黑色像素,则忽略它并继续搜索,因为这个黑色像素不存在?
答案 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;
}