You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 22:54:05