C#如何实现全屏幕特定颜色检测并将鼠标移动至目标颜色位置
如何修改C#脚本以检测屏幕任意位置的特定颜色并移动鼠标到该位置?
我编写了一段C#脚本,用于持续检测屏幕上是否存在特定颜色,但目前该脚本仅能检测鼠标所在的屏幕中间位置。请问如何修改才能实现检测屏幕任意位置的该特定颜色,并且在找到该颜色后将鼠标移动至该位置?以下是我的代码:
private bool SearchPixel(string hexcode) { Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics graphics = Graphics.FromImage(bitmap as Image); graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size); Color desiredPixelColor = ColorTranslator.FromHtml(hexcode); for (int x = 0; x < SystemInformation.VirtualScreen.Width; x++) { for (int y = 0; x < SystemInformation.VirtualScreen.Height; y++) { Color currentPixelColor = bitmap.GetPixel(x, y); if (desiredPixelColor == currentPixelColor) { MessageBox.Show("Found!"); return true; } } } }
让我来帮你解决这个问题,你的代码里有几个关键问题需要修正,同时我们要添加鼠标移动的逻辑,一步步来看:
1. 修复循环的致命错误
你内层循环的终止条件写错了——把y < SystemInformation.VirtualScreen.Height写成了x < SystemInformation.VirtualScreen.Height,这直接导致y永远不会递增,相当于只遍历了屏幕的第一行像素,这就是为什么你只能检测到某个固定区域的原因。
2. 统一屏幕区域的引用
现在你截图用的是主屏幕(Screen.PrimaryScreen)的尺寸,但循环遍历的是整个虚拟屏幕(SystemInformation.VirtualScreen)的范围,在多显示器场景下会出现不匹配的问题。建议统一使用VirtualScreen来处理,这样能覆盖所有连接的显示器。
3. 添加鼠标移动的核心逻辑
当找到目标颜色的像素时,我们需要把这个像素的坐标转换为屏幕绝对坐标,然后通过Cursor.Position属性直接设置鼠标位置。
4. 必须处理资源释放
Bitmap和Graphics都是非托管资源,如果不手动释放会造成内存泄漏,用using语句可以让系统自动帮我们释放这些资源,避免内存占用过高。
修改后的完整代码
using System.Drawing; using System.Windows.Forms; private bool SearchAndMoveToPixel(string hexcode) { // 获取包含所有显示器的虚拟屏幕区域 Rectangle virtualScreen = SystemInformation.VirtualScreen; // 使用using语句确保资源自动释放 using (Bitmap bitmap = new Bitmap(virtualScreen.Width, virtualScreen.Height)) { using (Graphics graphics = Graphics.FromImage(bitmap)) { // 截取整个虚拟屏幕的画面 graphics.CopyFromScreen(virtualScreen.X, virtualScreen.Y, 0, 0, virtualScreen.Size); } Color desiredPixelColor = ColorTranslator.FromHtml(hexcode); // 遍历屏幕上的每一个像素 for (int x = 0; x < virtualScreen.Width; x++) { for (int y = 0; y < virtualScreen.Height; y++) { Color currentPixelColor = bitmap.GetPixel(x, y); // 匹配到目标颜色时移动鼠标 if (currentPixelColor.Equals(desiredPixelColor)) { // 转换为屏幕绝对坐标(适配多显示器的偏移) Point targetPosition = new Point(virtualScreen.X + x, virtualScreen.Y + y); Cursor.Position = targetPosition; MessageBox.Show($"找到目标颜色!鼠标已移动至:({targetPosition.X}, {targetPosition.Y})"); return true; } } } } // 遍历完所有像素都没找到的情况 MessageBox.Show("未找到目标颜色!"); return false; }
额外的实用优化建议
- 提升检测速度:
GetPixel方法的性能比较差,如果需要频繁检测,可以改用LockBits方法直接访问图像内存,能大幅提升遍历效率。 - 实现持续检测:如果需要一直监控屏幕,可以把这个方法放到
Timer控件的定时事件里,或者在后台线程中循环执行(注意跨线程操作UI的问题,需要用Invoke)。 - 添加颜色容差:实际场景中屏幕颜色可能有细微偏差,你可以放弃精确匹配,改为判断RGB三个通道的差值是否在允许范围内,比如:
bool IsColorMatch(Color a, Color b, int tolerance) { return Math.Abs(a.R - b.R) <= tolerance && Math.Abs(a.G - b.G) <= tolerance && Math.Abs(a.B - b.B) <= tolerance; }
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

