Vix*_*inG 5 c# search screen pixel find
我想从屏幕上找到一个特定的像素坐标.这是我的代码(我是超级新手,我今天刚开始使用C#:
static string GetPixel(int X, int Y)
{
Point position = new Point(X, Y);
var bitmap = new Bitmap(1, 1);
var graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(position, new Point(0, 0), new Size(1, 1));
var _Pixel = bitmap.GetPixel(0, 0);
return "0x" + _Pixel.ToArgb().ToString("x").ToUpper().Remove(0, 2);
//it returns a pixel color in a form of "0xFFFFFF" hex code
//I had NO idea how to convert it to hex code so I did that :P
}
static void Main()
{
// for x = 1 to screen width...
for (int x = 1; x <= Screen.PrimaryScreen.Bounds.Bottom; x++)
{
// for x = 1 and y = 1 to screen height...
for (int y = 1; y <= Screen.PrimaryScreen.Bounds.Height; y++)
{
string pixel = GetPixel(x, y);
if (pixel == "0x007ACC") //blue color
{
MessageBox.Show("Found 0x007ACC at: (" + x + "," + y + ")");
break; //exit loop
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:这是我运行此脚本时出现的错误:
mscorlib.dll中发生未处理的"System.ArgumentOutOfRangeException"类型异常
附加信息:索引和长度必须指向字符串中的位置
我有AutoIt的经验,这是我与C#^^问候的第一天
欢迎来到SO。
大多数坐标和其他内容都是从 0 开始的,就像数组一样。
话虽这么说,最好对循环使用 Bounds 的 X/Y/Width 和 Height 属性:
var bounds = Screen.PrimaryScreen.Bounds;
for (int x = bounds.X; x < bounds.Width; x++) {
for(int y = bounds.Y; y < bounds.Height; y++) {
..
Run Code Online (Sandbox Code Playgroud)
将 ARGB 值转换为十六进制的正确方法是使用 string.Format ()方法:
string hex = string.Format("0x{0:8x}", argb);
编辑:显然Graphics.CopyFromScreen泄漏句柄就像没有明天一样,这会导致当没有更多句柄可用时抛出奇怪的异常(源代码)
针对您的场景的快速解决方法可能是捕获整个屏幕一次,然后在位图中搜索,即Graphics.CopyFromScreen(new Position(0, 0), new Position(0, 0), new Size(bounds.Width, bounds.Height));
不幸的是,这个问题在 .Net 4.0 中没有得到修复(不知道 4.5),因此唯一正确的解决方案似乎是 P/Invoke 原生 GDI 函数,如此处所述。