找色脚本看起来很简单:取一个颜色,再用 PixelSearch 去找。但实际写起来,经常会遇到这些问题:明明肉眼看到颜色在那里,脚本就是找不到;今天能用,换个窗口、换个缩放、换个主题就失效;取到的颜色值和截图软件看到的不一样。

我一般不建议一开始就把问题想复杂。找色不准,先从坐标、颜色格式、容差、搜索范围这几件事排查。很多脚本不是命令错了,而是取色和找色时用的规则不一致。

先固定坐标模式

找色脚本第一步,先把 Pixel 和 Mouse 的坐标模式写清楚。否则你以为自己在用屏幕坐标,实际可能是窗口坐标,位置一偏,后面怎么调颜色都没用。

#Requires AutoHotkey v1.1
CoordMode, Pixel, Screen
CoordMode, Mouse, Screen

F1::
MouseGetPos, x, y
PixelGetColor, color, %x%, %y%, RGB
MsgBox, 坐标:%x%, %y%`n颜色:%color%
return

这个小脚本很适合排查。鼠标移到目标位置,按 F1,看脚本实际取到的坐标和颜色。不要只相信肉眼,也不要只相信截图软件,先让 AHK 自己把结果报出来。

RGB 参数要一致

PixelGetColorPixelSearch 都要注意颜色格式。很多人拿到的是 RGB 颜色,却没有在命令里加 RGB 参数,结果颜色顺序对不上。【另外:原生的模糊找色(容差度variation)的性能效率较低】

CoordMode, Pixel, Screen

x1 := 500, y1 := 300, x2 := 900, y2 := 600
targetColor := 0xFFCC00
variation := 20

PixelSearch, fx, fy, %x1%, %y1%, %x2%, %y2%, %targetColor%, %variation%, Fast RGB
if ErrorLevel
    MsgBox, 没找到,先检查坐标范围、颜色值和容差
else
    MsgBox, % "找到:" fx "," fy

如果你取色时用了 RGB,找色时也尽量保持 RGB。这样文章、截图工具、代码里的颜色值更容易对应,不容易把自己绕晕。

先缩小搜索范围

找色不要动不动全屏搜。全屏搜索不仅慢,也更容易误匹配。能确定目标大概在哪个区域,就把范围限制到那个区域。

比如按钮只会出现在窗口右下角,那就只搜右下角。状态条只会在顶部,那就只搜顶部。范围越清楚,脚本越快,也越稳定。

取几个点看变化

如果你怀疑颜色不稳定,可以连续取几次同一个点,看颜色是否一直变化。

CoordMode, Pixel, Screen
x := 800, y := 450
text := ""

Loop, 8 {
    PixelGetColor, color, %x%, %y%, RGB
    text .= A_Index ": " color "`n"
    Sleep, 200
}

MsgBox, % text

如果每次颜色都不一样,就不要再按“固定颜色完全匹配”的思路写。这个时候要么放宽容差,要么改成区域判断、颜色相似度判断,或者换成 FindText 多点找色 或者 识别形状。

颜色相似度适合做二次判断

有些场景不是找一个点,而是判断一个颜色是否“接近”。这时可以把取到的颜色拆成 RGB,再比较三个通道的差值。

ColorNear(c1, c2, range := 20) {
    r1 := (c1 >> 16) & 255, g1 := (c1 >> 8) & 255, b1 := c1 & 255
    r2 := (c2 >> 16) & 255, g2 := (c2 >> 8) & 255, b2 := c2 & 255
    return Abs(r1-r2) <= range && Abs(g1-g2) <= range && Abs(b1-b2) <= range
}

PixelGetColor, nowColor, 800, 450, RGB
if ColorNear(nowColor, 0xFFCC00, 25)
    MsgBox, 颜色接近
else
    MsgBox, 颜色差异较大

这种写法比死盯一个颜色值更有弹性,适合做状态判断。但如果目标本身是图标、文字、按钮形状,就不要硬用单点颜色撑着。

什么时候该换 FindText

如果你要识别的是按钮、图标、文字、固定形状,而不是单纯判断一个颜色,我更建议转向 FindText。颜色判断适合“这个点是不是变色了”,FindText 更适合“这个目标有没有出现”。

尤其是你已经开始取很多点、写很多容差、担心按钮高亮状态、担心背景渐变时,就说明单纯找色已经不省心了。这个时候用 FindText 把目标特征提取出来,往往更容易维护。

什么时候用 WinCapture

如果你的脚本需要高频截图、快速取色、后台截图,或者一秒内反复判断画面状态,可以再考虑 WinCapture。普通脚本先把 PixelGetColorPixelSearch、FindText 的路线理顺,性能不够时再升级。

我的排查顺序

  • 先写明 CoordMode, Pixel, ScreenCoordMode, Mouse, Screen
  • PixelGetColor 直接取 AHK 看到的颜色。
  • 确认 RGB 参数前后一致。
  • 缩小搜索范围,不要全屏乱搜。
  • 连续取几次颜色,看它是否本身就在变化。
  • 单点颜色不稳定时,改成多点、区域或颜色相似度判断。
  • 目标是多点、区域、颜色相似度判断、图标、文字、按钮形状时,优先换 FindText
  • 高频截图取色时,再考虑 WinCapture

站内延伸

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。