以下是AHK单次找色和取色的效率,和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黄线边框的问题
Ø 缺点:只能指定窗口截图,不能截全屏。
文件与示例打包下载:
以下为AHKv1调用实现的示例,由于WGC要求版本高和绑定窗口后有黄线框,效率上和DWM一样。所以用DWM截图窗口即可
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)