以下是AHKv1单次找色和取色的效率,和10次截图并保存到文件的效率测试【计时单位为:毫秒】
因为用的是C++实现,所以能1毫秒内完成截图和取色找色,适合游戏压枪等需要高效率的场景
简介
GDI:第一代桌面采集
Windows 图形设备接口(GDI)是为与设备无关的图形设计的。基于 Windows 的应用程序不能直接访问图形硬件,应用程序通过 GDI 来与设备驱动程序进行交互。GDI 截图就是通过屏幕的DC获取到当前屏幕的位图数据。
Ø 特点:不受windows版本限制,基本兼容各版本的系统;
Ø 缺点:使用CPU,消耗大量cpu运算时间,若不单采鼠标,则使用gdi采集时,鼠标会出现闪烁,无法实现过滤指定窗口。
DXGI:高性能桌面采集技术
DXGI(Microsoft DirectX Graphics Infrastructure)是微软提供的一种可以在win8及以上系统使用的图形设备接口。它负责枚举图形适配器、枚举显示模式、选择缓冲区格式、在进程之间(例如,在应用程序和桌面窗口管理器(DWM)之间)共享资源,以及将呈现的帧传给窗口或监视器以供显示。其直接和硬件设备进行交互,具有很高的效率和性能。
Ø 特点:Win Vista 以后支持,使用GPU直接处理纹理,效率最高;
Ø 缺点:根据Direct3D 版本不同,存在硬件的支持以及调用特性 的区别。鼠标需要额外采集。
WGC:新世代采集技术
WGC 全称为 Windows Graphics Capture 是微软目前主推的一个桌面/窗口采集技术,使用 D3D11 库实现。该采集技术最早在Windows 10 18年3月份的更新中提供。WGC 对比放大镜采集(Magnification Capture) 具有更高的性能、更低CPU及GPU消耗。但是在 使用方面比起其他采集方式会更复杂。
Ø 特点:效率高,拓展屏采集支持高,1080p采集消耗gpu达到个位数;
Ø 缺点:系统要求高,需要WIN10 1903及以后版本才能支持。低版本系统绑定窗口会有黄线边框存在
DWM:窗口采集技术
DWM 全称为 Desktop Window Manager 是Windows操作系统中的一个窗口管理器,它负责管理桌面上的窗口和图形效果,包括透明效果、窗口动画等。通过DWM截图技术,可以捕捉到当前显示屏幕上所有窗口的内容,并保存为图像文件。
Ø 特点:效率高,支持窗口截图(不包括最小化窗口)。和WGC的性能一致,但不会有WGC黄线边框的问题
Ø 缺点:只能指定窗口截图,不能截全屏。
扩展阅读:FindText + WinCapture 结合使用 By FeiYue
AHKv1版文件与示例打包下载:
这段代码主要用于 屏幕截图、颜色检测、图片匹配 等操作。通过调用 AutoHotkey 加载的 WinCapture.dll
,实现了多种功能。以下是各功能的总结:
1. WinCapture.dll 加载与初始化
WinCapture_init()
:初始化WinCapture.dll
,为后续的屏幕截图与颜色/图片查找功能提供支持。
2. 截图与保存
- 功能:通过
DXGIcaptureAndSave()
截图,支持全屏或指定区域。- 示例:全屏截图、保存文件为
ScreenShot.bmp
。 - 支持将截图存入数组并批量保存。
- 还支持显示截图内容或调整截图大小后再显示。
- 示例:全屏截图、保存文件为
3. 单色查找与单点取色
- 功能:从截图中查找指定颜色的像素点或取单个像素的颜色值。
findColor(x, y, "0xFFFFFF")
:在截图中查找白色(0xFFFFFF)的像素点,返回坐标。getHexColor(x, y)
:获取指定像素坐标的颜色值。
4. 多色查找
- 功能:支持类似 FindText 的多点多色查找。
findMultiColors(x, y, [["0xFFFFFF", 0, 0], ["0xFFFFFF", 1, 0]])
:在指定区域内查找多个颜色的匹配点,返回匹配坐标。findAllMultiColors(RtnArray, arr)
:返回所有匹配的多色坐标,默认最多返回 20 个结果。- 支持将 FindText 的多色字符串格式转化为
WinCapture
识别的字典格式。
5. DWM 后台截图与图片匹配
- 功能:支持对特定窗口(如微信窗口)的后台截图,并进行图片匹配。
DWMcapture(hwnd)
:对特定窗口进行后台截图。findPic(x, y, 目标找图)
:在截图中查找指定图片,返回图片在屏幕上的坐标。findAllPic(RtnArray, 目标找图)
:返回所有匹配图片的坐标。
6. 快速统计颜色
- 功能:快速获取截图范围内的多个像素点颜色值,并统计颜色出现的次数。
- 支持指定截图范围(宽度、高度)。
- 输出目标颜色出现的次数、总像素数量,以及颜色的种类数量。
7. 图片加载与 GUI 显示
- 功能:加载图片文件并通过 AHK GUI 显示。
- 示例中加载
ScreenShot.bmp
,通过 GUI 添加Picture
控件显示。
- 示例中加载
以下为AHKv1调用的示例,由于WGC要求版本高和绑定窗口后有黄线框,效率上和DWM一样。所以用DWM截图窗口即可
; v2版原地址链接:https://github.com/thqby/ahk2_lib/tree/master/wincapture SetBatchLines -1 #SingleInstance Force WinCapture_init() ; WinCapture.dll加载与初始化 ; ==================== DXGI截图+单色查找与单点取色示例 ==================== 计时() tu := DXGIcaptureAndSave() ; 截屏取范围就是,范围找色 tu.findColor(x, y, "0xFFFFFF") ; 找色示例 Logg("全屏找色:" x ", " y " - 耗时:" 计时()) 计时() color := tu.getHexColor(x, y) ; 取色示例,示例沿用找到的x,y坐标。所以打印颜色只会是0xFFFFFF或者0【未找到】 Logg("取色数据:" color " 耗时:" 计时()) 计时() arr := [] Loop 10 { tu:=DXGIcaptureAndSave([960-320, 540-320, 960+320, 540+320]) ; 坐标系为xywh,示例参数为截图1080p中央部分 ; tu.Show() tu.Save("DXGIScreenShot.bmp") arr.push(tu) } Logg("10次截屏保存+数组 耗时:" 计时()) 计时() For _, _ in arr ; 将之前存到数组里的截图数据用另一个名称保存文件 _.Save("ArrScreenShot.bmp") Logg("10次数组读取+保存 耗时:" 计时()) Return ; ==================== 仿FindText多色查找+热键取色 ==================== ; WinCapture多色查找,找到立即返回坐标示例 Loop 10 { 计时() tu:=DXGIcaptureAndSave([500, 500, 1920, 1080]) ; 范围搜索 tu.findMultiColors(x, y, [["0xFFFFFF", 0, 0], ["0xFFFFFF", 1, 0]]) ; 多色查找-返回仅第一个坐标 Logg(x ", " y " 耗时:" 计时()) } Text:="|<>##0$0/0/723859,0/5/713859,0/8/723859,5/5/723859,10/2/723859,10/6/723859,10/9/723859,5/12/CAE4FC" arr := FtoW(Text) ; 将FindText的多色查找字符串,转换成WinCapture可识别的字典 ; arr:=[ ["0x723859", 0, 0], ["0x713859", 0, 5], ["0x723859", 0, 8], ["0x723859", 5, 5], ["0x723859", 10, 2], ["0x723859", 10, 6], ["0x723859", 10, 9], ["0xCAE4FC", 5, 12] ] ; WinCapture可识别的字典结构 计时() tu := DXGIcaptureAndSave() tu.findAllMultiColors(RtnArray, arr) ; 多色查找【默认返回20个匹配坐标】 Logg("全屏多色查找:" 计时()) Loop % RtnArray.Length() Logg("找到坐标" A_Index ":" RtnArray[A_Index]["x"] ", " RtnArray[A_Index]["y"]) F1:: x:=26, y:=12 tu := DXGIcaptureAndSave() color := tu.getHexColor(x, y) Logg("F1取色数据:" color) Return ; ==================== DWM实现后台截图找图 ==================== hwnd := WinExist("微信 ahk_class WeChatMainWndForPC") tu := DWMcapture(hwnd) ; 用DWM实现后台截图找图 tu.Show() ; 以下仅为找图片的示例,建议还是用多点找色取到目标的特征像素,来找更加好用。还不用附带图片文件 bmp := A_ScriptDir "\找图.bmp" ; 替换成自己想要找的目标截图 目标找图 := BitmapBuffer.LoadPicture(bmp) loop 10 { 计时() tu := DWMcapture(hwnd) tu.findPic(x, y, 目标找图) Logg(x ", " y " 耗时:" 计时()) } tu.findAllPic(RtnArray, 目标找图) ; 找图,返回找到的所有目标坐标 Loop % RtnArray.Length() Logg(RtnArray[A_Index]["x"] ", " RtnArray[A_Index]["y"]) ; ==================== 截图与保存文件 ==================== 计时() tu := DXGIcaptureAndSave() ; 不填范围为全屏截图 ; tu := DXGIcaptureAndSave([200, 200, 900, 999]) tu.Save("ScreenShot.bmp") ; 保存成文件 Logg("耗时:" 计时()) tu.Show("截图全屏窗口展示") 改变大小 := tu.range(900, 500) ; 改变截图大小 改变大小.Show("改变截图大小后的显示") ; ==================== 加载图片文件与Gui显示 ==================== bmp := A_ScriptDir "\ScreenShot.bmp" tu := BitmapBuffer.LoadPicture(bmp) ; tu.Show() hBitmap := tu.hBM() Gui Add, Picture, , % "HBITMAP:*" hBitmap Gui Show, AutoSize, AHK窗口显示写法 ; ==================== 复杂应用:快速获取多个颜色+统计颜色浓度 ==================== 计时() x1 := 0 y1 := 0 w := 110 h := 64 ; x1 := 146, y1 := 321, w := 616, h := 280 arr:=[] n := 0 tu := DXGIcaptureAndSave() Loop %w% { Loop %h% color:=tu.getHexColor(x1, y1+A_Index), arr[color] := arr[color] ? arr[color]+1 : 1, n++ x1++ } MsgBox % "指定坐标范围内色值出现的次数:" arr[0xFFFFFF] "`n指定坐标范围内的总像素:" n "`n耗时:" 计时() " ms" ; 键值总数量 MsgBox % "共捕获颜色数量:" arr.count() Return
评论(0)