FindText辅助工具
; 提示:鼠标移到屏幕边缘可调整抓图范围 ; 多次截图获取特征图像 v1.0 By FeiYue #NoEnv SetBatchLines, -1 FindText.Gui("Show") F2:: FindText.Gui("ScreenShot") ; 截屏热键 F1:: ; 生成特征图像的热键 ;---------------- mypic:="c:\a.bmp" ; 特征图像的保存文件路径 n:=10 ; 比较差异时允许的色偏(0-255) mycolor:=0xFF0000 ; 非特征色都改为透明色(红色) ;---------------- pos:=FindText.Gui("CaptureS") ; 查看截屏并选择范围(可清理) x1:=pos.1, y1:=pos.2, x2:=pos.3, y2:=pos.4 w:=x2-x1+1, h:=y2-y1+1, cc:=[] Loop, Files, % A_Temp "\Ahk_ScreenShot\*.bmp" { i:=A_Index, f:=A_LoopFileFullPath FindText.ShowPic(f,0) ; 打开每一张图片到内存但不显示 k:=0, (i=1 && f1:=f) ; 保留第一张图片的路径 Loop, % h { y:=y1+A_Index-1 Loop, % w { x:=x1+A_Index-1, c:=FindText.GetColor(x,y,0), v:=cc[++k] if (i=1) cc[k]:=c ; 读取第一张图片数据到数组 else if (v!="" and v!=c) and (Abs( (c&0xFF)-(v&0xFF) )>n or Abs( ((c>>8)&0xFF)-((v>>8)&0xFF) )>n or Abs( ((c>>16)&0xFF)-((v>>16)&0xFF) )>n) cc[k]:="" ; 其他图片数据与数组比较,色偏过大就数组清空 } } } FindText.ShowPic(f1,0), k:=0 ; 重新打开第一张图片到内存 Loop, % h { y:=y1+A_Index-1 Loop, % w { x:=x1+A_Index-1 if (cc[++k]="") || ((x=x1||x=x2)&&(y=y1||y=y2)) FindText.SetColor(x,y,mycolor) ; 根据数组修改第一张图片数据 } } FindText.SavePic(mypic, x1, y1, x2, y2, 0) ; 另存第一张图片数据 Run, % mypic return ;/* ;=========================================== ; FindText - 屏幕抓字生成字库工具与找字函数 ; https://autohotkey.com/boards/viewtopic.php?f=6&t=17834 ; ; 脚本作者 : FeiYue ; 最新版本 : 8.3 ; 更新时间 : 2021-03-19 ; ; 用法: (需要最新版本 AHK v1.1.31+) ; 1. 将本脚本保存为“FindText.ahk”并复制到AHK程序的Lib子目录中 ; 2. 抓图并生成调用FindText()的代码 ; 2.1 方式一:直接点击“抓图”按钮 ; 2.2 方式二:先设定截屏热键,使用热键截屏,再点击“截屏抓图”按钮 ; 3. 测试一下调用的代码是否成功:直接点击“测试”按钮 ; 4. 复制调用的代码到自己的脚本中 ; 4.1 方式一:直接点击“复制”按钮,然后粘贴到自己的脚本中(不推荐) ; 4.2 方式二:取消“附加FindText()函数”的选框,然后点击“复制”按钮, ; 然后粘贴到自己的脚本中,然后在自己的脚本开头加上一行: ; #Include <FindText> ; Lib目录中必须有FindText.ahk ; 5. 多色查找模式可以一定程度上适应图像的放大缩小,常用于游戏 ; 6. 这个库还可以用于快速截屏、获取颜色、写入颜色、编辑后另存图片 ; ;=========================================== ;*/ if (!A_IsCompiled and A_LineFile=A_ScriptFullPath) FindText.Gui("Show") ;===== Copy The Following Functions To Your Own Code Just once ===== ;-------------------------------- ; FindText - 屏幕找字函数 ;-------------------------------- ; 返回变量 := FindText( ; X1 --> 查找范围的左上角X坐标 ; , Y1 --> 查找范围的左上角Y坐标 ; , X2 --> 查找范围的右下角X坐标 ; , Y2 --> 查找范围的右下角Y坐标 ; , err1 --> 文字的黑点容错百分率(0.1=10%) ; , err0 --> 背景的白点容错百分率(0.1=10%) ; , Text --> 由工具生成的查找图像的数据,可以一次查找多个,用“|”分隔 ; , ScreenShot --> 是否截屏,为0则使用上一次的截屏数据 ; , FindAll --> 是否搜索所有位置,为0则找到一个位置就返回 ; , JoinText --> 是否组合图像,为1则多个数据组合为一幅图来查找 ; , offsetX --> 组合图像的每个字和前一个字的最大横向间隔 ; , offsetY --> 组合图像的每个字和前一个字的最大高低间隔 ; , dir --> 查找的方向,有上、下、左、右、中心5种 ; ) ; 返回变量 --> 如果没找到结果会返回0。否则返回一个二级数组, ; 第一级是每个结果对象,第二级是结果对象的具体信息数组: ; { 1:左上角X, 2:左上角Y, 3:图像宽度W, 4:图像高度H ; , x:中心点X, y:中心点Y, id:图像识别文本 } ; 坐标都是相对于屏幕,颜色使用RGB格式 ;-------------------------------- FindText(args*) { return FindText.FindText(args*) } Class FindText { ;// Class Begin static bind:=[], bits:=[], Lib:=[] __New() { this.bind:=[], this.bits:=[], this.Lib:=[] } __Delete() { if (this.bits.hBM) DllCall("DeleteObject", "Ptr",this.bits.hBM) } FindText(x1:=0, y1:=0, x2:=0, y2:=0, err1:=0, err0:=0 , text:="", ScreenShot:=1, FindAll:=1 , JoinText:=0, offsetX:=20, offsetY:=10, dir:=1) { local SetBatchLines, % (bch:=A_BatchLines)?"-1":"-1" centerX:=Round(x1+x2)//2, centerY:=Round(y1+y2)//2 if (x1*x1+y1*y1+x2*x2+y2*y2<=0) n:=150000, x:=y:=-n, w:=h:=2*n else x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy,zw,zh) , info:=[] Loop, Parse, text, | if IsObject(j:=this.PicInfo(A_LoopField)) info.Push(j) if (w<1 or h<1 or !(num:=info.MaxIndex()) or !bits.Scan0) { SetBatchLines, %bch% return 0 } arr:=[], in:={zx:zx, zy:zy, zw:zw, zh:zh , sx:x-zx, sy:y-zy, sw:w, sh:h}, k:=0 For i,j in info k:=Max(k, j.2*j.3), in.comment .= j.11 VarSetCapacity(s1, k*4), VarSetCapacity(s0, k*4) , VarSetCapacity(gs, (w+2)*(h+2)), VarSetCapacity(ss, w*h) , FindAll:=(dir=5 ? 1 : FindAll) , JoinText:=(num=1 ? 0 : JoinText) , allpos_max:=(FindAll or JoinText ? 10240 : 1) , VarSetCapacity(allpos, allpos_max*8) Loop, 2 { if (err1=0 and err0=0) and (num>1 or A_Index>1) err1:=0.05, err0:=0.05 Loop, % JoinText ? 1 : num { this.PicFind(arr, in, info, A_Index, err1, err0 , FindAll, JoinText, offsetX, offsetY, dir , bits, gs, ss, s1, s0, allpos, allpos_max) if (!FindAll and arr.MaxIndex()) Break } if (err1!=0 or err0!=0 or arr.MaxIndex() or info.1.12) Break } if (dir=5) arr:=this.Sort2(arr, centerX, centerY) SetBatchLines, %bch% return arr.MaxIndex() ? arr:0 } PicFind(arr, in, info, index, err1, err0 , FindAll, JoinText, offsetX, offsetY, dir , bits, ByRef gs, ByRef ss, ByRef s1, ByRef s0 , ByRef allpos, allpos_max) { local static MyFunc:="" if (!MyFunc) { x32:="" . "5557565383EC508B7C246483FF050F84B70200008B9C24AC00000085DB0F8E64" . "07000031C0897C2464C744240C00000000C744240800000000C7442404000000" . "0031EDC74424100000000089C78D76008B4C24088BB424A80000008B5C24108B" . "54240C01CE89C829CB8B8C24A8000000039C24A400000085C97E5889342489F9" . "89D6EB188BBC24A000000083C60483C0018914AF83C501390424742A837C2464" . "0389F20F45D0803C033175D88BBC249C00000083C60483C00139042489148F8D" . "790189F975D68BB424A80000000174241089CF83442404018B9C248C0000008B" . "442404015C24088B4C2478014C240C398424AC0000000F8554FFFFFF897C2424" . "8B7C246431C08B74242439B424B00000000F4DF039AC24B4000000897424240F" . "4DE839EE0F4CF583FF03897424280F84A70100008B4424788BB424840000000F" . "AF842488000000C1E6028974241001F08B742478894424348B84248C000000F7" . "D885FF8D0486894424140F85650300008B4424688BB42490000000C744241000" . "000000C744241800000000C1E8100FB6C0894424048B4424680FB6C489442408" . "0FB64424688944240C8B84248C000000C1E00285F6894424200F8EC50000008B" . "7C242C8B442434896C2430908D7426008B9C248C00000085DB0F8E830000008B" . "7424748B6C241803AC249800000001C6034424208944241C0344247489042490" . "0FB67E028B4C24040FB6160FB646012B54240C2B44240889FB01CF29CB8D8F00" . "0400000FAFC00FAFCBC1E00B0FAFCBBBFE05000029FB0FAFDA01C80FAFD301C2" . "3954246C0F93450083C60483C5013B342475AD8B9C248C000000015C24188B44" . "241C8344241001034424148B74241039B424900000000F8554FFFFFF8B6C2430" . "897C242C8B84248C0000002B8424A8000000C644241C00C644241400C7442404" . "00000000C7042400000000C744241801000000894424088B8424900000002B84" . "24AC0000008944240CEB6F8B44246C894424288B4424688944242C83FF058B84" . "248C000000C7442418000000000F9444241483FF030F9444241C038424840000" . "002B8424A8000000894424088B842488000000038424900000002B8424AC0000" . "008944240C8B842488000000894424048B8424840000008904248B44247083E8" . "0283F8020F8774090000837C2470020F8405030000837C2470030F8430030000" . "8B742408C7442410000000003B34248B7C24040F8CD30200003B7C240CC74424" . "3C040000000F8F8E060000807C24140089F80F8589060000807C241C000F8582" . "0700000FAF84248C0000008B54242801F085D289C1894424400F8E800000008B" . "8424B00000008B9C24B4000000038C2498000000897424308B742424897C2434" . "89D789442420895C243831C08D74260039C67E1C8B9C249C0000008B148301CA" . "803A00750B836C2420010F887308000039C57E1C8B9C24A00000008B148301CA" . "803A00740B836C2438010F885308000083C00139F875B98B7424308B7C24348B" . "5C242485DB74258B84249C0000008B8C24980000008B5424408D1C9801D18B10" . "83C00401CA39C3C6020075F28B5C24188B8424840000008B4C24108B9424B800" . "00000FAFC301F08904CA8B8424880000000FAFC301F88944CA0483C1013B8C24" . "BC000000894C24100F8D9E0100008B44243C83F8010F847801000083F8020F84" . "4C06000083F8030F84D807000083C701E9A4FEFFFF83FF010F84DE01000083FF" . "020F84AF0200008B4424680FB67C2468C744240C00000000C744241C00000000" . "C1E8100FB6D08B4424688914240FB654246C0FB6DC8B44246CC1E8100FB6C88B" . "44246C0FB6F48B042429C8030C248944242089D829F001DE8944240489D089FA" . "29C201F889742408894424188BB424900000008B84248C00000089542410890C" . "24C1E00285F6894424300F8E14FDFFFF896C24388B4C24348B6C24208D742600" . "8B9C248C00000085DB0F8E810000008B4424748B54241C0394249800000001C8" . "034C243089CF894C2420037C2474EB33391C247C3D394C24047F37394C24087C" . "3189F30FB6F3397424100F9EC3397424180F9DC183C00483C20121D9884AFF39" . "C7741E0FB658020FB648010FB63039DD7EBE31C983C00483C201884AFF39C775" . "E28BBC248C000000017C241C8B4C24208344240C01034C24148B44240C398424" . "900000000F8556FFFFFF8B6C2438E951FCFFFF83C6013B7424080F8ED8040000" . "83C7013B7C240C8B34247EEA8B44241083C4505B5E5F5DC25C008B7C240CC744" . "2410000000003B7C24048B34247CDD3B742408C744243C020000000F8E0AFDFF" . "FF83EF01EBE08D76008DBC27000000008B3424C7442410000000003B7424088B" . "7C24047FA73B7C240CC744243C030000000F8ED4FCFFFF83C601EBDF8B442468" . "8B8C2490000000C7042400000000C74424040000000083C001C1E00789442468" . "8B84248C000000C1E00285C98944240C0F8E8EFBFFFF896C24108B4424348B6C" . "24688B94248C00000085D27E5D8B4C24748B5C24048B7C2474039C2498000000" . "01C10344240C8944240801C78D7426000FB651020FB641010FB6316BC04B6BD2" . "2601C289F0C1E00429F001D039C50F970383C10483C30139F975D58BB4248C00" . "0000017424048B44240883042401034424148B3C2439BC249000000075848B6C" . "2410E9FDFAFFFF31EDC744242400000000E96EF9FFFF8B84248C000000038424" . "840000008BB42488000000894424148B84248800000083EE0103842490000000" . "89342439F00F8C0B0100008BB4248400000083C0012BBC248400000089442418" . "8B442414C744240C00000000896C243083EE018974241C8B342401C70FAF7424" . "78897C2420897424088D700189F78B44241C394424140F8C9D0000008B0C248B" . "5C24088B74240C035C24102BB42484000000035C2474C1E91F03B42494000000" . "894C2404EB538D76008DBC27000000003944247C7E4C807C24040075458B0C24" . "398C24800000007E390FB64BFE83C3046BE9260FB64BF96BD14B8D4C15000FB6" . "6BF889EAC1E20429EA01CAC1FA078854060183C00139F8741889C2C1EA1F84D2" . "74AEC64406010083C00183C30439F875E88B7424200174240C830424018B5C24" . "788B0424015C2408394424180F853CFFFFFF8B6C24308B84248C00000083C002" . "894424108B84249000000085C00F8E91F9FFFF8B44241003842494000000C744" . "240801000000C744240C00000000896C241C894424048B84249000000083C001" . "894424148B84248C00000083C004894424188B44246C8BBC248C00000085FF0F" . "8EA00000008B5424048B5C240C8B742418039C249800000089D12B8C248C0000" . "0001D6890C248D76008DBC27000000000FB642010FB62ABF0100000003442468" . "39E8723C0FB66A0239E872348B0C240FB669FF39E872290FB66EFF39E872210F" . "B669FE39E872190FB62939E872120FB66EFE39E873578D76008DBC2700000000" . "89F98304240183C201880B83C60183C3018B3C24397C240475968BB4248C0000" . "000174240C83442408018B5C24108B7C2408015C2404397C24140F8536FFFFFF" . "8B6C241C8944246CE977F8FFFF0FB63E39F80F92C189CFEBA783EE01E94BF9FF" . "FF0FAF4424788B54242885D28D04B0894424300F8E33FAFFFF8B8424B0000000" . "31DB896C243889742440897C2444894424208B44242CF7D889442434EB4E89F2" . "0FB6F289FA0FB6EE89FA29EE89F50FB6F28B54242C29F13B44243489CE0F9CC1" . "39EA0F9CC009C13B6C24340F9CC009C839F20F9CC108C8755B3B7424347C5583" . "C3013B5C24280F84E40100008B84249C0000008B4C2430030C988B8424A00000" . "008B3C988B44247489FE0FB6440802C1EE1089F20FB6F28B54247429F0394424" . "2C8B7424740FB6740E010FB60C0A0F8D6AFFFFFF836C24200179A4897C24688B" . "6C24388B7424408B7C2444E99EF9FFFF83C601E957FBFFFFC744243C01000000" . "E966F8FFFF0FAF4424788B5C24748D04B089442430034424680FB65C0302895C" . "24208B5C24740FB65C0301895C24348B5C24740FB60403894424388B44242885" . "C00F8E05F9FFFF8B8424B400000031D289742440897C24448944244C8B8424B0" . "000000894424488B44242C395424247E6A8B84249C0000008B7424300334900F" . "B64433020FB64C33010FB634332B4C24342B74243889C7034424202B7C24200F" . "AFC98974242C8DB000040000C1E10B0FAFF70FAFF78B7C242C01F1BEFE050000" . "29C60FAFF70FAFF701CE3974246C730B836C2448010F88B200000039D57E668B" . "8424A00000008B7424300334900FB64433020FB64C33010FB634332B4C24342B" . "74243889C7034424202B7C24200FAFC98974242C8DB000040000C1E10B0FAFF7" . "0FAFF78B7C242C01F1BEFE05000029C60FAFF70FAFF701CE3974246C7207836C" . "244C01784883C2013B5424280F8519FFFFFF8944242C8B7424408B7C2444E9E9" . "F7FFFF8B7424308B7C2434E91EF8FFFF897C24688B6C24388B7424408B7C2444" . "E9C7F7FFFF83C701E9F8F9FFFF8944242C8B7424408B7C2444E9F0F7FFFF8B7C" . "2404C744241000000000E974F9FFFF90" x64:="" . "4157415641554154555756534883EC58448BB424F00000004C8BAC2418010000" . "83F90589542418448944241C44898C24B80000000F84A00200008BAC24300100" . "004531D24531FF85ED0F8EC50000004489B424F0000000488BB4241001000045" . "31E4448BB4242801000031FF31ED4531D24531FFC704240000000044895C2410" . "4585F67E6348631424418D1C3E89F848039424200100004589E0EB1F0F1F4000" . "83C0014D63DA4183C0044183C2014883C20139C347894C9D00742983F9034589" . "C1440F45C8803A3175D683C0014D63DF4183C0044183C7014883C20139C34689" . "0C9E75D74401342483C50103BC24F00000004403A424C800000039AC24300100" . "000F8579FFFFFF448B5C2410448BB424F000000031C04439BC2438010000440F" . "4DF84439942440010000440F4DD04539D74489D0410F4DC783F903894424280F" . "84A20100008B8424C80000008BBC24E00000000FAF8424E80000008D04B88BBC" . "24C8000000894424204489F0F7D885C98D0487894424080F85730300008B7C24" . "1889FE4889F8440FB6E78BBC24F8000000C1EE100FB6C4400FB6F689C385FF0F" . "8EF8000000428D04B50000000044897C24304C89AC2418010000448B7C242044" . "8B6C241CBDFE050000C7042400000000C74424100000000089DF894424144489" . "54242C4585F60F8E86000000488B9C24C00000004963C74531D24C8D4C030248" . "635C241048039C24080100000F1F4000450FB619410FB651FE410FB641FF4429" . "E24489D94101F34189D0418D930004000029F129F80FAFD10FAFC00FAFD1C1E0" . "0B8D040289EA4429DA410FAFD0410FAFD001D04139C5420F9304134983C20149" . "83C1044539D67FA844037C241444017424108304240144037C24088B04243984" . "24F80000000F8558FFFFFF448B54242C448B7C24304C8BAC24180100004489F0" . "2B842428010000C644242C00C644241400C704240000000031EDC74424200100" . "0000894424108B8424F80000002B84243001000089442408EB648B44241C448B" . "5C2418894424288B8424E000000083F9058BAC24E00000000F9444241483F903" . "C7442420000000000F9444242C4401F02B842428010000894424108B8424E800" . "0000038424F80000002B842430010000894424088B8424E80000008904248B84" . "24B800000083E80283F8020F871F0A000083BC24B8000000020F84E702000083" . "BC24B8000000030F84030300008B7424104531E439EE8B3C240F8CB30200003B" . "7C2408C744243C040000000F8FF8060000807C24140089F80F85F3060000807C" . "242C000F85F60700008B4C2428410FAFC685C9448D04300F8E8B000000448964" . "24308974243831C0448B8C24400100008B9C24380100004C8BA4240801000048" . "8BB4241001000044895C24344189CB904139C789C17E198B14864401C24863D2" . "41803C1400750983EB010F88200900004139CA7E1C418B5485004401C24863D2" . "41803C1400740A4183E9010F88FF0800004883C0014139C37FB6448B64243044" . "8B5C24348B7424384585FF742F488B842410010000418D57FF4C8B8C24080100" . "00488D4C90048B104883C0044401C24839C84863D241C604110075EA438D0424" . "8B5C2420488B8C24480100004183C4014863D08B8424E00000000FAFC301F089" . "04918B8424E80000000FAFC301F8443BA42450010000894491040F8D72010000" . "8B44243C83F8010F844D01000083F8020F84B406000083F8030F847B08000083" . "C701E998FEFFFF660F1F84000000000083F9010F849C01000083F9020F84A702" . "00008B74241889F0440FB6C6C1E8104489C30FB6F84889F08B74241C0FB6CC41" . "89CC89F0440FB6CE4489E5C1E8104429CB0FB6D04889F0891C240FB6C489FE01" . "D789C129C54489C84401C0448B8424F800000029D689C3428D04B50000000041" . "01CC31D231C94585C0894424100F8E2AFDFFFF44895C242C448B5C242044897C" . "24304C89AC24180100004189DF448954241489CB4189D5660F1F840000000000" . "4585F60F8ECF010000488B8C24C00000004963C34D63D531D24C039424080100" . "00488D440102EB3C0F1F8400000000004439C77C4139CD7F3D4139CC7C384439" . "0C24410F9EC04539CF0F9DC14421C141880C124883C2014883C0044139D60F8E" . "6C010000440FB6000FB648FF440FB648FE4439C67EBA31C9EBD583C6013B7424" . "100F8E6B05000083C7013B7C240889EE7EEB4489E04883C4585B5E5F5D415C41" . "5D415E415FC38B7C24084531E43B3C2489EE7CDE3B742410C744243C02000000" . "0F8E2BFDFFFF83EF01EBE20F1F44000089EE4531E43B7424108B3C247FB43B7C" . "2408C744243C030000000F8E01FDFFFF83C601EBE08B5424188B9C24F8000000" . "31F631FF428D2CB50000000083C201C1E20785DB895424180F8EDFFBFFFF4489" . "5C241044897C24144C89AC24180100008B5C2420448B5C24184C8BA424C00000" . "00448BBC24F8000000448B6C2408448914244585F67E524C63D74C0394240801" . "00004863C3498D4C04024531C00F1F000FB6110FB641FF440FB649FE6BC04B6B" . "D22601C24489C8C1E0044429C801D04139C3430F9704024983C0014883C10445" . "39C67FCC01EB4401F783C6014401EB4139F7759E448B1424448B5C2410448B7C" . "24144C8BAC2418010000E92EFBFFFF9044035C24104501F583C30144035C2408" . "399C24F80000000F8513FEFFFF448B542414448B5C242C448B7C24304C8BAC24" . "18010000E9F4FAFFFF8B8424E00000008BBC24E80000004401F08D6FFF890424" . "8B8424E8000000038424F800000039E80F8C5C0100008BBC24E000000083C001" . "8BB424C8000000894424102B8C24E000000031DB4489542430448B9424D00000" . "0083EF0144897C243844895C243489F8897C24084189DFC1E0024489B424F000" . "00004C89AC24180100000FAFF589442414489848894424208B042489F78BB424" . "D800000001C1448D6001894C242C8B4424083904240F8CA40000008B5C24144C" . "8B7424204D63C74C63EF4C038424000100008D141F89EBC1EB1F4863D24989D1" . "4929D64C038C24C0000000EB500F1F004139C27E5184DB754D39EE7E49410FB6" . "490283C0014983C001446BD926410FB649016BD14B418D0C134B8D140E4983C1" . "04460FB61C2A4489DAC1E2044429DA01CAC1FA07418850FF4139C4741D89C2C1" . "EA1F84D274AA83C00141C600004983C1044983C0014139C475E344037C242C83" . "C50103BC24C8000000396C24100F853BFFFFFF448B542430448B5C2434448B7C" . "2438448BB424F00000004C8BAC2418010000448B8C24F8000000418D46024585" . "C90F8E56F9FFFF488BBC240001000048988B54241C4889042444897C242CBD01" . "0000004C89AC24180100004531E44489542414488D7C07018B8424F800000044" . "895C242083C001894424104963C6488D700348F7D04889C3418D46FF4889F18B" . "7424184989DF4883C0014989CD48894424084585F60F8E90000000488B442408" . "4963CC48038C24080100004D8D4C3D004D8D043F488D1C384889F80F1F440000" . "0FB610440FB650FF41BB0100000001F24439D2723B440FB650014439D2723145" . "0FB650FF4439D27227450FB651FF4439D2721D450FB650FE4439D27213450FB6" . "104439D2720A450FB651FE4439D2734C4883C0014488194983C1014883C10149" . "83C0014839D875984501F483C50148033C24396C24100F8556FFFFFF448B5424" . "14448B5C2420448B7C242C8954241C4C8BAC2418010000E921F8FFFF450FB611" . "4439D2410F92C3EBA783EE01E9E3F8FFFF0FAF8424C80000008B54242885D244" . "8D04B00F8ED3F9FFFF8B9C24380100004489D84531C9F7D84489542430448964" . "24348944244089742438895C2418488B9424C0000000EB4D4889F30FB6DF4129" . "DA8B5C24404589D4440FB6D64429D139D84189CA0F9CC14539E30F9CC009C141" . "39DC0F9CC009C84539D30F9CC108C8755B4139DA7C564983C10144394C24280F" . "8E1E020000488B842410010000438B748D00428B0C884189F241C1EA10450FB6" . "D24401C18D410248980FB604024429D0448D51014863C94139C30FB60C0A4D63" . "D2460FB614120F8D6CFFFFFF836C24180179A389742418448B542430448B6424" . "348B742438E936F9FFFF83C601E9C2FAFFFFC744243C01000000E9F2F7FFFF0F" . "AF8424C8000000488B9C24C00000008D04B089442430034424188D50024863D2" . "0FB61C138D500148984863D289D9488B9C24C00000000FB61C13895C2434488B" . "9C24C00000000FB60403894424388B44242885C00F8E82F8FFFF8B8424400100" . "008974244489CE488B8C24C000000031DB44896424408944244C8B8424380100" . "00894424484139DF4189D97E76488B8424100100008B5424300314988D420248" . "98440FB61C018D42014863D20FB6141148982B5424380FB604014589DC4101F3" . "2B442434458D83000400004129F4450FAFC40FAFC0450FAFC4C1E00B4401C041" . "B8FE0500004529D8440FAFC2410FAFD001C23954241C730B836C2448010F88BF" . "0000004539CA7E6C8B5424304103549D008D42024898440FB61C018D42014863" . "D20FB6141148982B5424380FB604014589D94101F32B442434458D8300040000" . "4129F1450FAFC10FAFC0450FAFC1C1E00B4401C041B8FE0500004529D8440FAF" . "C2410FAFD001C23954241C7207836C244C01784E4883C301395C24280F8F03FF" . "FFFF448B6424408B742444E94CF7FFFF448B642430448B5C24348B742438E97D" . "F7FFFF89742418448B542430448B6424348B742438E922F7FFFF83C701E91CF9" . "FFFF448B6424408B742444E950F7FFFF8B3C244531E4E9AFF8FFFF9090909090" this.MCode(MyFunc, A_PtrSize=8 ? x64:x32) } num:=info.MaxIndex(), j:=info[index] , text:=j.1, w:=j.2, h:=j.3, len1:=j.4, len0:=j.5 , e1:=(j.12 ? j.6 : Round(len1*err1)) , e0:=(j.12 ? j.7 : Round(len0*err0)) , mode:=j.8, color:=j.9, n:=j.10, comment:=j.11 , sx:=in.sx, sy:=in.sy, sw:=in.sw, sh:=in.sh, Stride:=bits.Stride if (JoinText and index>1) { x:=in.x, y:=in.y, sw:=Min(x+offsetX+w,sx+sw), sx:=x, sw-=sx , sh:=Min(y+offsetY+h,sy+sh), sy:=Max(y-offsetY,sy), sh-=sy } if (mode=5) { ListLines, % (lls:=A_ListLines)?"Off":"Off" r:=StrSplit(text,"/"), i:=0, k:=-4 Loop, % n NumPut(r[i+2]*Stride+r[i+1]*4, s1, k+=4, "int") , NumPut(r[i+=3], s0, k, "int") ListLines, %lls% } else if (mode=3) { color:=(color//w)*Stride+Mod(color,w)*4 } ok:=!bits.Scan0 ? 0:DllCall(&MyFunc , "int",mode, "uint",color, "uint",n, "int",dir , "Ptr",bits.Scan0, "int",Stride, "int",in.zw, "int",in.zh , "int",sx, "int",sy, "int",sw, "int",sh , "Ptr",&gs, "Ptr",&ss, "Ptr",&s1, "Ptr",&s0 , "AStr",text, "int",w, "int",h, "int",e1, "int",e0 , "Ptr",&allpos, "int",allpos_max) pos:=[] Loop, % ok pos.Push( NumGet(allpos, 8*A_Index-8, "uint") , NumGet(allpos, 8*A_Index-4, "uint") ) Loop, % ok { x:=pos[2*A_Index-1], y:=pos[2*A_Index] if (!JoinText) { x1:=x+in.zx, y1:=y+in.zy , arr.Push( {1:x1, 2:y1, 3:w, 4:h , x:x1+w//2, y:y1+h//2, id:comment} ) } else if (index=1) { in.x:=x+w, in.y:=y, in.minY:=y, in.maxY:=y+h Loop, % num-1 if !this.PicFind(arr, in, info, A_Index+1, err1, err0 , FindAll, JoinText, offsetX, offsetY, 3 , bits, gs, ss, s1, s0, allpos, 1) Continue, 2 x1:=x+in.zx, y1:=in.minY+in.zy , w1:=in.x-x, h1:=in.maxY-in.minY , arr.Push( {1:x1, 2:y1, 3:w1, 4:h1 , x:x1+w1//2, y:y1+h1//2, id:in.comment} ) } else { in.x:=x+w, in.y:=y , (y<in.minY && in.minY:=y) , (y+h>in.maxY && in.maxY:=y+h) return 1 } if (!FindAll and arr.MaxIndex()) return } } GetBitsFromScreen(ByRef x, ByRef y, ByRef w, ByRef h , ScreenShot:=1, ByRef zx:="", ByRef zy:="" , ByRef zw:="", ByRef zh:="") { local static Ptr:="Ptr" bits:=this.bits if (!ScreenShot) { zx:=bits.zx, zy:=bits.zy, zw:=bits.zw, zh:=bits.zh if IsByRef(x) w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y return bits } bch:=A_BatchLines, cri:=A_IsCritical Critical if (id:=this.BindWindow(0,0,1)) { WinGet, id, ID, ahk_id %id% WinGetPos, zx, zy, zw, zh, ahk_id %id% } if (!id) { SysGet, zx, 76 SysGet, zy, 77 SysGet, zw, 78 SysGet, zh, 79 } bits.zx:=zx, bits.zy:=zy, bits.zw:=zw, bits.zh:=zh , w:=Min(x+w,zx+zw), x:=Max(x,zx), w-=x , h:=Min(y+h,zy+zh), y:=Max(y,zy), h-=y if (zw>bits.oldzw or zh>bits.oldzh or !bits.hBM) { hBM:=bits.hBM , VarSetCapacity(bi, 40, 0), NumPut(40, bi, 0, "int") , NumPut(zw, bi, 4, "int"), NumPut(-zh, bi, 8, "int") , NumPut(1, bi, 12, "short"), NumPut(bpp:=32, bi, 14, "short") , bits.hBM:=DllCall("CreateDIBSection", Ptr,0, Ptr,&bi , "int",0, "Ptr*",ppvBits:=0, Ptr,0, "int",0, Ptr) , bits.Scan0:=(!bits.hBM ? 0:ppvBits) , bits.Stride:=((zw*bpp+31)//32)*4 , bits.oldzw:=zw, bits.oldzh:=zh , DllCall("DeleteObject", Ptr,hBM) } if (bits.hBM) and !(w<1 or h<1) { mDC:=DllCall("CreateCompatibleDC", Ptr,0, Ptr) oBM:=DllCall("SelectObject", Ptr,mDC, Ptr,bits.hBM, Ptr) if (id) { if (mode:=this.BindWindow(0,0,0,1))<2 { hDC2:=DllCall("GetDCEx", Ptr,id, Ptr,0, "int",3, Ptr) DllCall("BitBlt",Ptr,mDC,"int",x-zx,"int",y-zy,"int",w,"int",h , Ptr,hDC2, "int",x-zx, "int",y-zy, "uint",0xCC0020|0x40000000) DllCall("ReleaseDC", Ptr,id, Ptr,hDC2) } else { VarSetCapacity(bi, 40, 0), NumPut(40, bi, 0, "int") NumPut(zw, bi, 4, "int"), NumPut(-zh, bi, 8, "int") NumPut(1, bi, 12, "short"), NumPut(32, bi, 14, "short") hBM2:=DllCall("CreateDIBSection", Ptr,0, Ptr,&bi , "int",0, "Ptr*",0, Ptr,0, "int",0, Ptr) mDC2:=DllCall("CreateCompatibleDC", Ptr,0, Ptr) oBM2:=DllCall("SelectObject", Ptr,mDC2, Ptr,hBM2, Ptr) DllCall("PrintWindow", Ptr,id, Ptr,mDC2, "uint",(mode>3)*3) DllCall("BitBlt",Ptr,mDC,"int",x-zx,"int",y-zy,"int",w,"int",h , Ptr,mDC2, "int",x-zx, "int",y-zy, "uint",0xCC0020|0x40000000) DllCall("SelectObject", Ptr,mDC2, Ptr,oBM2) DllCall("DeleteDC", Ptr,mDC2) DllCall("DeleteObject", Ptr,hBM2) } } else { win:=DllCall("GetDesktopWindow", Ptr) hDC:=DllCall("GetWindowDC", Ptr,win, Ptr) DllCall("BitBlt",Ptr,mDC,"int",x-zx,"int",y-zy,"int",w,"int",h , Ptr,hDC, "int",x, "int",y, "uint",0xCC0020|0x40000000) DllCall("ReleaseDC", Ptr,win, Ptr,hDC) } if this.CaptureCursor(0,0,0,0,0,1) this.CaptureCursor(mDC, zx, zy, zw, zh) DllCall("SelectObject", Ptr,mDC, Ptr,oBM) DllCall("DeleteDC", Ptr,mDC) } Critical, %cri% SetBatchLines, %bch% return bits } PicInfo(text) { local static info:=[] if !InStr(text,"$") return if (info[text]) return info[text] v:=text, comment:="", seterr:=e1:=e0:=0 ; You Can Add Comment Text within The <> if RegExMatch(v,"<([^>]*)>",r) v:=StrReplace(v,r), comment:=Trim(r1) ; You can Add two fault-tolerant in the [], separated by commas if RegExMatch(v,"\[([^\]]*)]",r) { v:=StrReplace(v,r), r:=StrSplit(r1, ",") , seterr:=1, e1:=r.1, e0:=r.2 } r:=StrSplit(v,"$"), color:=r.1, v:=r.2 mode:=InStr(color,"##") ? 5 : InStr(color,"-") ? 4 : InStr(color,"#") ? 3 : InStr(color,"**") ? 2 : InStr(color,"*") ? 1 : 0 color:=RegExReplace(color,"[*#]") if (mode=5) { v:=Trim(StrReplace(RegExReplace(v,"\s"),",","/"),"/") r:=StrSplit(v,"/"), n:=r.MaxIndex()//3 if (!n) return v:="", x1:=x2:=r.1, y1:=y2:=r.2, i:=j:=1 ListLines, % (lls:=A_ListLines)?"Off":"Off" Loop, % n x:=r[i++], y:=r[i++], i++ , (x<x1 && x1:=x), (x>x2 && x2:=x) , (y<y1 && y1:=y), (y>y2 && y2:=y) Loop, % n v.="/" (r[j++]-x1) "/" (r[j++]-y1) "/" . Floor("0x" r[j++])&0xFFFFFF ListLines, %lls% v:=SubStr(v,2), w:=x2-x1+1, h:=y2-y1+1 , len1:=n, e1:=Round(len1*e1), len0:=0 } else { r:=StrSplit(v,"."), w:=r.1 , v:=this.base64tobit(r.2), h:=StrLen(v)//w if (w<1 or h<1 or StrLen(v)!=w*h) return if (mode=4) { r:=StrSplit(StrReplace(color,"0x"),"-") , color:=Round("0x" r.1), n:=Round("0x" r.2) } else { r:=StrSplit(color,"@") , color:=r.1, n:=Round(r.2,2)+(!r.2) , n:=Floor(512*9*255*255*(1-n)*(1-n)) } StrReplace(v,"1","",len1), len0:=StrLen(v)-len1 , e1:=Round(len1*e1), e0:=Round(len0*e0) } return info[text]:=[v,w,h,len1,len0,e1,e0 , mode,color,n,comment,seterr] } ; 绑定窗口从而可以后台查找这个窗口的图像 ; 相当于始终在前台。解绑窗口使用 FindText.BindWindow(0) BindWindow(bind_id:=0, bind_mode:=0, get_id:=0, get_mode:=0) { local bind:=this.bind if (get_id) return bind.id if (get_mode) return bind.mode if (bind_id) { bind.id:=bind_id, bind.mode:=bind_mode, bind.oldStyle:=0 if (bind_mode & 1) { WinGet, oldStyle, ExStyle, ahk_id %bind_id% bind.oldStyle:=oldStyle WinSet, Transparent, 255, ahk_id %bind_id% Loop, 30 { Sleep, 100 WinGet, i, Transparent, ahk_id %bind_id% } Until (i=255) } } else { bind_id:=bind.id if (bind.mode & 1) WinSet, ExStyle, % bind.oldStyle, ahk_id %bind_id% bind.id:=0, bind.mode:=0, bind.oldStyle:=0 } } ; 使用 FindText.CaptureCursor(1) 设置抓图时捕获鼠标 ; 使用 FindText.CaptureCursor(0) 取消抓图时捕获鼠标 CaptureCursor(hDC:=0, zx:=0, zy:=0, zw:=0, zh:=0, get_cursor:=0) { local if (get_cursor) return this.Cursor if (hDC=1 or hDC=0) and (zw=0) { this.Cursor:=hDC return } Ptr:=(A_PtrSize ? "Ptr":"UInt"), PtrSize:=(A_PtrSize=8 ? 8:4) VarSetCapacity(mi, 40, 0), NumPut(16+PtrSize, mi, "int") DllCall("GetCursorInfo", Ptr,&mi) bShow := NumGet(mi, 4, "int") hCursor := NumGet(mi, 8, Ptr) x := NumGet(mi, 8+PtrSize, "int") y := NumGet(mi, 12+PtrSize, "int") if (!bShow) or (x<zx or y<zy or x>=zx+zw or y>=zy+zh) return VarSetCapacity(ni, 40, 0) DllCall("GetIconInfo", Ptr,hCursor, Ptr,&ni) xCenter := NumGet(ni, 4, "int") yCenter := NumGet(ni, 8, "int") hBMMask := NumGet(ni, (PtrSize=8?16:12), Ptr) hBMColor := NumGet(ni, (PtrSize=8?24:16), Ptr) DllCall("DrawIconEx", Ptr,hDC , "int",x-xCenter-zx, "int",y-yCenter-zy, Ptr,hCursor , "int",0, "int",0, "int",0, "int",0, "int",3) DllCall("DeleteObject", Ptr,hBMMask) DllCall("DeleteObject", Ptr,hBMColor) } MCode(ByRef code, hex) { local ListLines, % (lls:=A_ListLines)?"Off":"Off" SetBatchLines, % (bch:=A_BatchLines)?"-1":"-1" VarSetCapacity(code, len:=StrLen(hex)//2) Loop, % len NumPut("0x" SubStr(hex,2*A_Index-1,2),code,A_Index-1,"uchar") DllCall("VirtualProtect","Ptr",&code,"Ptr",len,"uint",0x40,"Ptr*",0) SetBatchLines, %bch% ListLines, %lls% } base64tobit(s) { local Chars:="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZ" . "abcdefghijklmnopqrstuvwxyz" ListLines, % (lls:=A_ListLines)?"Off":"Off" Loop, Parse, Chars { i:=A_Index-1, v:=(i>>5&1) . (i>>4&1) . (i>>3&1) . (i>>2&1) . (i>>1&1) . (i&1) s:=RegExReplace(s,"[" A_LoopField "]",StrReplace(v,"0x")) } ListLines, %lls% return RegExReplace(RegExReplace(s,"10*$"),"[^01]+") } bit2base64(s) { local s:=RegExReplace(s,"[^01]+") s.=SubStr("100000",1,6-Mod(StrLen(s),6)) s:=RegExReplace(s,".{6}","|$0") Chars:="0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZ" . "abcdefghijklmnopqrstuvwxyz" ListLines, % (lls:=A_ListLines)?"Off":"Off" Loop, Parse, Chars { i:=A_Index-1, v:="|" . (i>>5&1) . (i>>4&1) . (i>>3&1) . (i>>2&1) . (i>>1&1) . (i&1) s:=StrReplace(s,StrReplace(v,"0x"),A_LoopField) } ListLines, %lls% return s } xywh2xywh(x1,y1,w1,h1, ByRef x, ByRef y, ByRef w, ByRef h , ByRef zx:="", ByRef zy:="", ByRef zw:="", ByRef zh:="") { local SysGet, zx, 76 SysGet, zy, 77 SysGet, zw, 78 SysGet, zh, 79 w:=Min(x1+w1,zx+zw), x:=Max(x1,zx), w-=x , h:=Min(y1+h1,zy+zh), y:=Max(y1,zy), h-=y } ASCII(s) { local if RegExMatch(s,"\$(\d+)\.([\w+/]+)",r) { s:=RegExReplace(this.base64tobit(r2),".{" r1 "}","$0`n") s:=StrReplace(StrReplace(s,"0","_"),"1","0") } else s= return s } ; 可以在脚本的开头用 FindText.PicLib(Text,1) 导入字库, ; 然后使用 FindText.PicLib("说明文字1|说明文字2|...") 获取字库中的数据 PicLib(comments, add_to_Lib:=0, index:=1) { local Lib:=this.Lib if (add_to_Lib) { re:="<([^>]*)>[^$]+\$\d+\.[\w+/]+" Loop, Parse, comments, | if RegExMatch(A_LoopField,re,r) { s1:=Trim(r1), s2:="" Loop, Parse, s1 s2.="_" . Format("{:d}",Ord(A_LoopField)) Lib[index,s2]:=r } Lib[index,""]:="" } else { Text:="" Loop, Parse, comments, | { s1:=Trim(A_LoopField), s2:="" Loop, Parse, s1 s2.="_" . Format("{:d}",Ord(A_LoopField)) Text.="|" . Lib[index,s2] } return Text } } ; 分割字符串为单个文字并获取数据 PicN(Number, index:=1) { return this.PicLib(RegExReplace(Number,".","|$0"), 0, index) } ; 使用 FindText.PicX(Text) 可以将文字分割成多个单字的组合,从而适应间隔变化 ; 但是不能用于“颜色位置二值化”模式, 因为位置是与整体图像相关的 PicX(Text) { local if !RegExMatch(Text,"(<[^$]+)\$(\d+)\.([\w+/]+)",r) return Text v:=this.base64tobit(r3), Text:="" c:=StrLen(StrReplace(v,"0"))<=StrLen(v)//2 ? "1":"0" txt:=RegExReplace(v,".{" r2 "}","$0`n") While InStr(txt,c) { While !(txt~="m`n)^" c) txt:=RegExReplace(txt,"m`n)^.") i:=0 While (txt~="m`n)^.{" i "}" c) i:=Format("{:d}",i+1) v:=RegExReplace(txt,"m`n)^(.{" i "}).*","$1") txt:=RegExReplace(txt,"m`n)^.{" i "}") if (v!="") Text.="|" r1 "$" i "." this.bit2base64(v) } return Text } ; 截屏,作为后续操作要用的“上一次的截屏” ScreenShot(x1:=0, y1:=0, x2:=0, y2:=0) { this.FindText(x1, y1, x2, y2) } ; 从“上一次的截屏”中快速获取指定坐标的RGB颜色 ; 如果坐标超出了屏幕范围,将返回白色 GetColor(x, y, fmt:=1) { local bits:=this.GetBitsFromScreen(0,0,0,0,0,zx,zy,zw,zh) , c:=(x<zx or x>=zx+zw or y<zy or y>=zy+zh or !bits.Scan0) ? 0xFFFFFF : NumGet(bits.Scan0+(y-zy)*bits.Stride+(x-zx)*4,"uint") return (fmt ? Format("0x{:06X}",c&0xFFFFFF) : c) } ; 在最后一个屏幕截图中设置点的RGB颜色 SetColor(x, y, color:=0x000000) { local bits:=this.GetBitsFromScreen(0,0,0,0,0,zx,zy,zw,zh) if !(x<zx or x>=zx+zw or y<zy or y>=zy+zh or !bits.Scan0) NumPut(color,bits.Scan0+(y-zy)*bits.Stride+(x-zx)*4,"uint") } ; 根据 FindText() 的结果识别一行文字或验证码 ; offsetX 为两个文字的最大间隔,超过会插入*号 ; offsetY 为两个文字的最大高度差 ; 最后返回数组:{text:识别结果, x:结果左上角X, y:结果左上角Y, w:宽, h:高} Ocr(ok, offsetX:=20, offsetY:=20) { local ocr_Text:=ocr_X:=ocr_Y:=min_X:=dx:="" For k,v in ok x:=v.1 , min_X:=(A_Index=1 or x<min_X ? x : min_X) , max_X:=(A_Index=1 or x>max_X ? x : max_X) While (min_X!="" and min_X<=max_X) { LeftX:="" For k,v in ok { x:=v.1, y:=v.2 if (x<min_X) or Abs(y-ocr_Y)>offsetY Continue ; Get the leftmost X coordinates if (LeftX="" or x<LeftX) LeftX:=x, LeftY:=y, LeftW:=v.3, LeftH:=v.4, LeftOCR:=v.id } if (LeftX="") Break if (ocr_X="") ocr_X:=LeftX, min_Y:=LeftY, max_Y:=LeftY+LeftH ; If the interval exceeds the set value, add "*" to the result ocr_Text.=(ocr_Text!="" and LeftX>dx ? "*":"") . LeftOCR ; Update for next search min_X:=LeftX+LeftW-LeftW//2, dx:=LeftX+LeftW+offsetX , ocr_Y:=LeftY, (LeftY<min_Y && min_Y:=LeftY) , (LeftY+LeftH>max_Y && max_Y:=LeftY+LeftH) } return {text:ocr_Text, x:ocr_X, y:min_Y , w: min_X-ocr_X, h: max_Y-min_Y} } ; 按照从左到右、从上到下的顺序排序FindText()的结果 ; 忽略轻微的Y坐标差距,返回排序后的数组对象 Sort(ok, dy:=10) { local if !IsObject(ok) return ok ypos:=[] For k,v in ok { x:=v.x, y:=v.y, add:=1 For k2,v2 in ypos if Abs(y-v2)<=dy { y:=v2, add:=0 Break } if (add) ypos.Push(y) n:=(y*150000+x) "." k, s:=A_Index=1 ? n : s "-" n } Sort, s, N D- ok2:=[] Loop, Parse, s, - ok2.Push( ok[(StrSplit(A_LoopField,".")[2])] ) return ok2 } ; 以指定点为中心,按从近到远排序FindText()的结果 ; 返回排序后的数组对象 Sort2(ok, px, py) { local if !IsObject(ok) return ok For k,v in ok n:=((v.x-px)**2+(v.y-py)**2) "." k, s:=A_Index=1 ? n : s "-" n Sort, s, N D- ok2:=[] Loop, Parse, s, - ok2.Push( ok[(StrSplit(A_LoopField,".")[2])] ) return ok2 } ; 提示某个坐标的位置,或远程控制中当前鼠标的位置 MouseTip(x:="", y:="", w:=10, h:=10, d:=4) { local if (x="") { VarSetCapacity(pt,16,0), DllCall("GetCursorPos","ptr",&pt) x:=NumGet(pt,0,"uint"), y:=NumGet(pt,4,"uint") } x:=Round(x-w-d), y:=Round(y-h-d), w:=(2*w+1)+2*d, h:=(2*h+1)+2*d ;------------------------- Gui, _MouseTip_: +AlwaysOnTop -Caption +ToolWindow +Hwndmyid -DPIScale Gui, _MouseTip_: Show, Hide w%w% h%h% ;------------------------- DetectHiddenWindows, % (dhw:=A_DetectHiddenWindows)?"On":"On" i:=w-d, j:=h-d s=0-0 %w%-0 %w%-%h% 0-%h% 0-0 %d%-%d% %i%-%d% %i%-%j% %d%-%j% %d%-%d% WinSet, Region, %s%, ahk_id %myid% DetectHiddenWindows, %dhw% ;------------------------- Gui, _MouseTip_: Show, NA x%x% y%y% Loop, 4 { Gui, _MouseTip_: Color, % A_Index & 1 ? "Red" : "Blue" Sleep, 500 } Gui, _MouseTip_: Destroy } ; 快速获取屏幕图像的搜索文本数据 GetTextFromScreen(x1, y1, x2, y2, Threshold:="" , ScreenShot:=1, ByRef rx:="", ByRef ry:="") { local SetBatchLines, % (bch:=A_BatchLines)?"-1":"-1" x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy,zw,zh) if (w<1 or h<1) { SetBatchLines, %bch% return } ListLines, % (lls:=A_ListLines)?"Off":"Off" gs:=[], k:=0 Loop, %h% { j:=y+A_Index-1 Loop, %w% i:=x+A_Index-1, c:=this.GetColor(i,j,0) , gs[++k]:=(((c>>16)&0xFF)*38+((c>>8)&0xFF)*75+(c&0xFF)*15)>>7 } if InStr(Threshold,"**") { Threshold:=StrReplace(Threshold,"*") if (Threshold="") Threshold:=50 s:="", sw:=w, w-=2, h-=2, x++, y++ Loop, %h% { y1:=A_Index Loop, %w% x1:=A_Index, i:=y1*sw+x1+1, j:=gs[i]+Threshold , s.=( gs[i-1]>j || gs[i+1]>j || gs[i-sw]>j || gs[i+sw]>j || gs[i-sw-1]>j || gs[i-sw+1]>j || gs[i+sw-1]>j || gs[i+sw+1]>j ) ? "1":"0" } Threshold:="**" Threshold } else { Threshold:=StrReplace(Threshold,"*") if (Threshold="") { pp:=[] Loop, 256 pp[A_Index-1]:=0 Loop, % w*h pp[gs[A_Index]]++ IP:=IS:=0 Loop, 256 k:=A_Index-1, IP+=k*pp[k], IS+=pp[k] Threshold:=Floor(IP/IS) Loop, 20 { LastThreshold:=Threshold IP1:=IS1:=0 Loop, % LastThreshold+1 k:=A_Index-1, IP1+=k*pp[k], IS1+=pp[k] IP2:=IP-IP1, IS2:=IS-IS1 if (IS1!=0 and IS2!=0) Threshold:=Floor((IP1/IS1+IP2/IS2)/2) if (Threshold=LastThreshold) Break } } s:="" Loop, % w*h s.=gs[A_Index]<=Threshold ? "1":"0" Threshold:="*" Threshold } ;-------------------- w:=Format("{:d}",w), CutUp:=CutDown:=0 re1=(^0{%w%}|^1{%w%}) re2=(0{%w%}$|1{%w%}$) While RegExMatch(s,re1) s:=RegExReplace(s,re1), CutUp++ While RegExMatch(s,re2) s:=RegExReplace(s,re2), CutDown++ rx:=x+w//2, ry:=y+CutUp+(h-CutUp-CutDown)//2 s:="|<>" Threshold "$" w "." this.bit2base64(s) ;-------------------- SetBatchLines, %bch% ListLines, %lls% return s } ; 快速保存截图为BMP文件,可用于调试 SavePic(file, x1:=0, y1:=0, x2:=0, y2:=0, ScreenShot:=1) { local static Ptr:="Ptr" if (x1*x1+y1*y1+x2*x2+y2*y2<=0) n:=150000, x:=y:=-n, w:=h:=2*n else x:=Min(x1,x2), y:=Min(y1,y2), w:=Abs(x2-x1)+1, h:=Abs(y2-y1)+1 bits:=this.GetBitsFromScreen(x,y,w,h,ScreenShot,zx,zy,zw,zh) if (w<1 or h<1 or !bits.hBM) return VarSetCapacity(bi, 40, 0), NumPut(40, bi, 0, "int") NumPut(w, bi, 4, "int"), NumPut(h, bi, 8, "int") NumPut(1, bi, 12, "short"), NumPut(bpp:=24, bi, 14, "short") hBM:=DllCall("CreateDIBSection", Ptr,0, Ptr,&bi , "int",0, "Ptr*",ppvBits:=0, Ptr,0, "int",0, Ptr) mDC:=DllCall("CreateCompatibleDC", Ptr,0, Ptr) oBM:=DllCall("SelectObject", Ptr,mDC, Ptr,hBM, Ptr) ;------------------------- mDC2:=DllCall("CreateCompatibleDC", Ptr,0, Ptr) oBM2:=DllCall("SelectObject", Ptr,mDC2, Ptr,bits.hBM, Ptr) DllCall("BitBlt",Ptr,mDC,"int",0,"int",0,"int",w,"int",h , Ptr,mDC2, "int",x-zx, "int",y-zy, "uint",0xCC0020) DllCall("SelectObject", Ptr,mDC2, Ptr,oBM2) DllCall("DeleteDC", Ptr,mDC2) ;------------------------- size:=((w*bpp+31)//32)*4*h VarSetCapacity(bf, 14, 0), StrPut("BM", &bf, "CP0") NumPut(54+size, bf, 2, "uint"), NumPut(54, bf, 10, "uint") f:=FileOpen(file,"w"), f.RawWrite(bf,14), f.RawWrite(bi,40) , f.RawWrite(ppvBits+0, size), f.Close() ;------------------------- DllCall("SelectObject", Ptr,mDC, Ptr,oBM) DllCall("DeleteDC", Ptr,mDC) DllCall("DeleteObject", Ptr,hBM) } ; 显示保存的BMP图像 ShowPic(file:="", show:=1) { local static Ptr:="Ptr" Gui, FindText_Screen: Destroy if (file="") or !FileExist(file) return hBM:=LoadPicture(file) mDC:=DllCall("CreateCompatibleDC", Ptr,0, Ptr) oBM:=DllCall("SelectObject", Ptr,mDC, Ptr,hBM, Ptr) ;---------------------- bits:=this.GetBitsFromScreen(0,0,0,0,1,zx,zy,zw,zh) mDC2:=DllCall("CreateCompatibleDC", Ptr,0, Ptr) oBM2:=DllCall("SelectObject", Ptr,mDC2, Ptr,bits.hBM, Ptr) DllCall("BitBlt", Ptr,mDC2, "int",0, "int",0, "int",zw, "int",zh , Ptr,mDC, "int",0, "int",0, "uint",0xCC0020) DllCall("SelectObject", Ptr,mDC2, Ptr,oBM2) DllCall("DeleteDC", Ptr,mDC2) ;---------------------- DllCall("SelectObject", Ptr,mDC, Ptr,oBM) DllCall("DeleteDC", Ptr,mDC) DllCall("DeleteObject", Ptr,hBM), hBM:=bits.hBM if (!show) return Gui, FindText_Screen: +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000 Gui, FindText_Screen: Margin, 0, 0 Gui, FindText_Screen: Add, Pic,, HBITMAP:*%hBM% Gui, FindText_Screen: Show, NA x%zx% y%zy% w%zw% h%zh%, Show Pic } ; 动态运行AHK代码作为新线程 Class Thread { __New(args*) { this.pid:=this.Exec(args*) } __Delete() { Process, Close, % this.pid } Exec(s, Ahk:="", args:="") { local Ahk:=Ahk ? Ahk:A_IsCompiled ? A_ScriptDir "\AutoHotkey.exe":A_AhkPath s:="DllCall(""SetWindowText"",""Ptr"",A_ScriptHwnd,""Str"",""<AHK>"")`n" . StrReplace(s,"`r"), pid:="" Try { shell:=ComObjCreate("WScript.Shell") oExec:=shell.Exec("""" Ahk """ /f * " args) oExec.StdIn.Write(s) oExec.StdIn.Close(), pid:=oExec.ProcessID } Catch { f:=A_Temp "\~ahk.tmp" s:="`n FileDelete, " f "`n" s FileDelete, %f% FileAppend, %s%, %f% r:=ObjBindMethod(this, "Clear") SetTimer, %r%, -3000 Run, "%Ahk%" /f "%f%" %args%,, UseErrorLevel, pid } return pid } Clear() { FileDelete, % A_Temp "\~ahk.tmp" SetTimer,, Off } } WindowToScreen(ByRef x, ByRef y, id:="") { local WinGetPos, winx, winy,,, % id ? "ahk_id " id : "A" x+=Floor(winx), y+=Floor(winy) } ScreenToWindow(ByRef x, ByRef y, id:="") { local this.WindowToScreen(dx:=0, dy:=0, id), x-=dx, y-=dy } ClientToScreen(ByRef x, ByRef y, id:="") { local if (!id) WinGet, id, ID, A VarSetCapacity(pt,8,0), NumPut(0,pt,"int64") , DllCall("ClientToScreen","Ptr",id,"Ptr",&pt) , x+=NumGet(pt,"int"), y+=NumGet(pt,4,"int") } ScreenToClient(ByRef x, ByRef y, id:="") { local this.ClientToScreen(dx:=0, dy:=0, id), x-=dx, y-=dy } QPC() ; <==> A_TickCount { local static c:=0, f:=0, init:=DllCall("QueryPerformanceFrequency", "Int*",f) return (!DllCall("QueryPerformanceCounter","Int64*",c))*0+(c/f)*1000 } ; 不像 FindText 总是使用屏幕坐标,它使用与内置命令 ; ImageSearch 一样的 CoordMode 设置的坐标模式 ImageSearch(ByRef rx, ByRef ry, x1, y1, x2, y2, text) { local dx:=dy:=0 if (A_CoordModePixel="Window") this.WindowToScreen(dx, dy) else if (A_CoordModePixel="Client") this.ClientToScreen(dx, dy) if (ok:=this.FindText(x1+dx, y1+dy, x2+dx, y2+dy, 0, 0, text, 1, 0)) { rx:=ok.1.x-dx, ry:=ok.1.y-dy, ErrorLevel:=0 return 1 } else { rx:=ry:="", ErrorLevel:=1 return 0 } } /***** 机器码的 C语言 源代码 ***** int __attribute__((__stdcall__)) PicFind( int mode, unsigned int c, unsigned int n, int dir , unsigned char * Bmp, int Stride, int zw, int zh , int sx, int sy, int sw, int sh , unsigned char * gs, char * ss, int * s1, int * s0 , char * text, int w, int h, int err1, int err0 , unsigned int * allpos, int allpos_max ) { int ok=0, o, i, j, k, v, r, g, b, rr, gg, bb; int x, y, x1, y1, x2, y2, len1, len0, e1, e0, max; int r_min, r_max, g_min, g_max, b_min, b_max; //---------------------- // 多色模式 if (mode==5) { max=n; v=c; goto StartLookUp; } //---------------------- // 生成查表需要的表格 o=0; len1=0; len0=0; for (y=0; y<h; y++) { for (x=0; x<w; x++) { i=(mode==3) ? y*Stride+x*4 : y*sw+x; if (text[o++]=='1') s1[len1++]=i; else s0[len0++]=i; } } if (err1>=len1) len1=0; if (err0>=len0) len0=0; max=(len1>len0) ? len1 : len0; //---------------------- // 颜色位置模式 // 仅用于多色验证码的识别 if (mode==3) goto StartLookUp; //---------------------- // 生成二值化图像 o=sy*Stride+sx*4; j=Stride-sw*4; i=0; if (mode==0) // 颜色相似二值化 { rr=(c>>16)&0xFF; gg=(c>>8)&0xFF; bb=c&0xFF; for (y=0; y<sh; y++, o+=j) for (x=0; x<sw; x++, o+=4, i++) { r=Bmp[2+o]-rr; g=Bmp[1+o]-gg; b=Bmp[o]-bb; v=r+rr+rr; ss[i]=((1024+v)*r*r+2048*g*g+(1534-v)*b*b<=n) ? 1:0; } } else if (mode==1) // 灰度阈值二值化 { c=(c+1)<<7; for (y=0; y<sh; y++, o+=j) for (x=0; x<sw; x++, o+=4, i++) ss[i]=(Bmp[2+o]*38+Bmp[1+o]*75+Bmp[o]*15<c) ? 1:0; } else if (mode==2) // 灰度差值二值化 { x2=sx+sw; y2=sy+sh; for (y=sy-1; y<=y2; y++) { for (x=sx-1; x<=x2; x++, i++) if (x<0 || x>=zw || y<0 || y>=zh) gs[i]=0; else { o=y*Stride+x*4; gs[i]=(Bmp[2+o]*38+Bmp[1+o]*75+Bmp[o]*15)>>7; } } k=sw+2; i=0; for (y=1; y<=sh; y++) for (x=1; x<=sw; x++, i++) { o=y*k+x; n=gs[o]+c; ss[i]=(gs[o-1]>n || gs[o+1]>n || gs[o-k]>n || gs[o+k]>n || gs[o-k-1]>n || gs[o-k+1]>n || gs[o+k-1]>n || gs[o+k+1]>n) ? 1:0; } } else // (mode==4) 颜色分量二值化 { r=(c>>16)&0xFF; g=(c>>8)&0xFF; b=c&0xFF; rr=(n>>16)&0xFF; gg=(n>>8)&0xFF; bb=n&0xFF; r_min=r-rr; g_min=g-gg; b_min=b-bb; r_max=r+rr; g_max=g+gg; b_max=b+bb; for (y=0; y<sh; y++, o+=j) for (x=0; x<sw; x++, o+=4, i++) { r=Bmp[2+o]; g=Bmp[1+o]; b=Bmp[o]; ss[i]=(r>=r_min && r<=r_max && g>=g_min && g<=g_max && b>=b_min && b<=b_max) ? 1:0; } } //---------------------- StartLookUp: if (mode==5 || mode==3) { x1=sx; y1=sy; x2=sx+sw-w; y2=sy+sh-h; k=0; } else { x1=0; y1=0; x2=sw-w; y2=sh-h; k=1; } if (dir<1 || dir>4) dir=1; if (dir==1) // 从上到下 { for (y=y1; y<=y2; y++) { for (x=x1; x<=x2; x++) { goto GoSub; GoBack1:; } } } else if (dir==2) // 从下到上 { for (y=y2; y>=y1; y--) { for (x=x1; x<=x2; x++) { goto GoSub; GoBack2:; } } } else if (dir==3) // 从左到右 { for (x=x1; x<=x2; x++) { for (y=y1; y<=y2; y++) { goto GoSub; GoBack3:; } } } else // (dir==4) 从右到左 { for (x=x2; x>=x1; x--) { for (y=y1; y<=y2; y++) { goto GoSub; GoBack4:; } } } goto Return1; //---------------------- GoSub: if (mode==5) { o=y*Stride+x*4; e1=err1; for (i=0; i<max; i++) { j=o+s1[i]; c=s0[i]; r=Bmp[2+j]-((c>>16)&0xFF); g=Bmp[1+j]-((c>>8)&0xFF); b=Bmp[j]-(c&0xFF); if ((r>v||r<-v||g>v||g<-v||b>v||b<-v) && (--e1)<0) goto NoMatch; } } else if (mode==3) { o=y*Stride+x*4; e1=err1; e0=err0; j=o+c; rr=Bmp[2+j]; gg=Bmp[1+j]; bb=Bmp[j]; for (i=0; i<max; i++) { if (i<len1) { j=o+s1[i]; r=Bmp[2+j]-rr; g=Bmp[1+j]-gg; b=Bmp[j]-bb; v=r+rr+rr; if ((1024+v)*r*r+2048*g*g+(1534-v)*b*b>n && (--e1)<0) goto NoMatch; } if (i<len0) { j=o+s0[i]; r=Bmp[2+j]-rr; g=Bmp[1+j]-gg; b=Bmp[j]-bb; v=r+rr+rr; if ((1024+v)*r*r+2048*g*g+(1534-v)*b*b<=n && (--e0)<0) goto NoMatch; } } } else { o=y*sw+x; e1=err1; e0=err0; for (i=0; i<max; i++) { if (i<len1 && ss[o+s1[i]]==0 && (--e1)<0) goto NoMatch; if (i<len0 && ss[o+s0[i]]!=0 && (--e0)<0) goto NoMatch; } // 清空已经找到的图像 for (i=0; i<len1; i++) ss[o+s1[i]]=0; } allpos[ok*2]=k*sx+x; allpos[ok*2+1]=k*sy+y; if (++ok>=allpos_max) goto Return1; NoMatch: if (dir==1) goto GoBack1; if (dir==2) goto GoBack2; if (dir==3) goto GoBack3; goto GoBack4; //---------------------- Return1: return ok; } */ ;==== Optional GUI interface ==== Gui(cmd, arg1:="") { local static global FindText local lls, bch, cri ListLines, % InStr("|KeyDown|LButtonDown|MouseMove|" , "|" cmd "|") ? "Off" : A_ListLines static init:=0 if (!init) { init:=1 Gui_:=ObjBindMethod(FindText,"Gui") Gui_G:=ObjBindMethod(FindText,"Gui","G") Gui_Run:=ObjBindMethod(FindText,"Gui","Run") Gui_Off:=ObjBindMethod(FindText,"Gui","Off") Gui_Show:=ObjBindMethod(FindText,"Gui","Show") Gui_KeyDown:=ObjBindMethod(FindText,"Gui","KeyDown") Gui_LButtonDown:=ObjBindMethod(FindText,"Gui","LButtonDown") Gui_MouseMove:=ObjBindMethod(FindText,"Gui","MouseMove") Gui_ScreenShot:=ObjBindMethod(FindText,"Gui","ScreenShot") Gui_ShowPic:=ObjBindMethod(FindText,"Gui","ShowPic") Gui_ToolTip:=ObjBindMethod(FindText,"Gui","ToolTip") Gui_ToolTipOff:=ObjBindMethod(FindText,"Gui","ToolTipOff") bch:=A_BatchLines, cri:=A_IsCritical Critical #NoEnv %Gui_%("Load_Language_Text") %Gui_%("MakeCaptureWindow") %Gui_%("MakeMainWindow") OnMessage(0x100, Gui_KeyDown) OnMessage(0x201, Gui_LButtonDown) OnMessage(0x200, Gui_MouseMove) Menu, Tray, Add Menu, Tray, Add, % Lang["1"], %Gui_Show% if (!A_IsCompiled and A_LineFile=A_ScriptFullPath) { Menu, Tray, Default, % Lang["1"] Menu, Tray, Click, 1 Menu, Tray, Icon, Shell32.dll, 23 } Critical, %cri% SetBatchLines, %bch% } Switch cmd { Case "Off": return Case "G": GuiControl, +g, %id%, %Gui_Run% return Case "Run": Critical %Gui_%(A_GuiControl) return Case "Show": Gui, FindText_Main: Default Gui, Show, Center GuiControl, Focus, scr return Case "MakeCaptureWindow": ww:=35, hh:=12, WindowColor:="0xDDEEFF" Gui, FindText_Capture: New Gui, +AlwaysOnTop -DPIScale Gui, Margin, 15, 15 Gui, Color, %WindowColor% Gui, Font, s12, Verdana Gui, -Theme nW:=71, nH:=25, w:=12, C_:=[], Cid_:=[] Loop, % nW*(nH+1) { i:=A_Index, j:=i=1 ? "" : Mod(i,nW)=1 ? "xm y+1":"x+1" j.=i>nW*nH ? " cRed BackgroundFFFFAA" : "" Gui, Add, Progress, w%w% h%w% %j% Hwndid Control, ExStyle, -0x20000,, ahk_id %id% C_[i]:=id, Cid_[id]:=i } Gui, +Theme GuiControlGet, p, Pos, %id% w:=pX+pW-15, h:=pY+pH-15 Gui, Add, Slider, xm w%w% vMySlider1 Hwndid Disabled +Center Page20 Line10 NoTicks AltSubmit %Gui_G%() Gui, Add, Slider, ym h%h% vMySlider2 Hwndid Disabled +Center Page20 Line10 NoTicks AltSubmit +Vertical %Gui_G%() GuiControlGet, p, Pos, %id% k:=pX+pW, MySlider1:=MySlider2:=dx:=dy:=0 ;-------------- Gui, Add, Button, xm Hwndid Hidden Section, % Lang["Auto"] GuiControlGet, p, Pos, %id% w:=Round(pW*0.75), i:=Round(w*3+15+pW*0.5-w*1.5) Gui, Add, Button, xm+%i% yp w%w% hp -Wrap vRepU Hwndid, % Lang["RepU"] %Gui_G%() Gui, Add, Button, x+0 wp hp -Wrap vCutU Hwndid, % Lang["CutU"] %Gui_G%() Gui, Add, Button, x+0 wp hp -Wrap vCutU3 Hwndid, % Lang["CutU3"] %Gui_G%() Gui, Add, Button, xm wp hp -Wrap vRepL Hwndid, % Lang["RepL"] %Gui_G%() Gui, Add, Button, x+0 wp hp -Wrap vCutL Hwndid, % Lang["CutL"] %Gui_G%() Gui, Add, Button, x+0 wp hp -Wrap vCutL3 Hwndid, % Lang["CutL3"] %Gui_G%() Gui, Add, Button, x+15 w%pW% hp -Wrap vAuto Hwndid, % Lang["Auto"] %Gui_G%() Gui, Add, Button, x+15 w%w% hp -Wrap vRepR Hwndid, % Lang["RepR"] %Gui_G%() Gui, Add, Button, x+0 wp hp -Wrap vCutR Hwndid, % Lang["CutR"] %Gui_G%() Gui, Add, Button, x+0 wp hp -Wrap vCutR3 Hwndid, % Lang["CutR3"] %Gui_G%() Gui, Add, Button, xm+%i% wp hp -Wrap vRepD Hwndid, % Lang["RepD"] %Gui_G%() Gui, Add, Button, x+0 wp hp -Wrap vCutD Hwndid, % Lang["CutD"] %Gui_G%() Gui, Add, Button, x+0 wp hp -Wrap vCutD3 Hwndid, % Lang["CutD3"] %Gui_G%() ;-------------- Gui, Add, Text, x+80 ys+3 Section, % Lang["SelGray"] Gui, Add, Edit, x+3 yp-3 w60 vSelGray ReadOnly Gui, Add, Text, x+15 ys, % Lang["SelColor"] Gui, Add, Edit, x+3 yp-3 w120 vSelColor ReadOnly Gui, Add, Text, x+15 ys, % Lang["SelR"] Gui, Add, Edit, x+3 yp-3 w60 vSelR ReadOnly Gui, Add, Text, x+5 ys, % Lang["SelG"] Gui, Add, Edit, x+3 yp-3 w60 vSelG ReadOnly Gui, Add, Text, x+5 ys, % Lang["SelB"] Gui, Add, Edit, x+3 yp-3 w60 vSelB ReadOnly ;-------------- x:=w*6+pW+15*4, w:=k-x Gui, Add, Tab3, x%x% y+15 w%w% -Wrap, % Lang["2"] Gui, Tab, 1 Gui, Add, Text, x+15 y+15, % Lang["Threshold"] Gui, Add, Edit, x+15 w100 vThreshold Gui, Add, Button, x+15 yp-3 vGray2Two Hwndid, % Lang["Gray2Two"] %Gui_G%() Gui, Tab, 2 Gui, Add, Text, x+15 y+15, % Lang["GrayDiff"] Gui, Add, Edit, x+15 w100 vGrayDiff, 50 Gui, Add, Button, x+15 yp-3 vGrayDiff2Two Hwndid, % Lang["GrayDiff2Two"] %Gui_G%() Gui, Tab, 3 Gui, Add, Text, x+15 y+15, % Lang["Similar1"] " 0" Gui, Add, Slider, x+0 w120 vSimilar1 Hwndid +Center Page1 NoTicks ToolTip, 100 %Gui_G%() Gui, Add, Text, x+0, 100 Gui, Add, Button, x+15 yp-3 vColor2Two Hwndid, % Lang["Color2Two"] %Gui_G%() Gui, Tab, 4 Gui, Add, Text, x+15 y+15, % Lang["Similar2"] " 0" Gui, Add, Slider, x+0 w120 vSimilar2 Hwndid +Center Page1 NoTicks ToolTip, 100 %Gui_G%() Gui, Add, Text, x+0, 100 Gui, Add, Button, x+15 yp-3 vColorPos2Two Hwndid, % Lang["ColorPos2Two"] %Gui_G%() Gui, Tab, 5 Gui, Add, Text, x+10 y+15, % Lang["DiffR"] Gui, Add, Edit, x+5 w80 vDiffR Limit3 Gui, Add, UpDown, vdR Range0-255 Wrap Gui, Add, Text, x+5, % Lang["DiffG"] Gui, Add, Edit, x+5 w80 vDiffG Limit3 Gui, Add, UpDown, vdG Range0-255 Wrap Gui, Add, Text, x+5, % Lang["DiffB"] Gui, Add, Edit, x+5 w80 vDiffB Limit3 Gui, Add, UpDown, vdB Range0-255 Wrap Gui, Add, Button, x+15 yp-3 vColorDiff2Two Hwndid, % Lang["ColorDiff2Two"] %Gui_G%() Gui, Tab, 6 Gui, Add, Text, x+10 y+15, % Lang["DiffRGB"] Gui, Add, Edit, x+5 w80 vDiffRGB Limit3 Gui, Add, UpDown, vdRGB Range0-255 Wrap Gui, Add, Checkbox, x+15 yp+5 vMultiColor Hwndid, % Lang["MultiColor"] %Gui_G%() Gui, Add, Button, x+15 yp-5 vUndo Hwndid, % Lang["Undo"] %Gui_G%() Gui, Tab ;-------------- Gui, Add, Button, xm vReset Hwndid, % Lang["Reset"] %Gui_G%() Gui, Add, Checkbox, x+15 yp+5 vModify Hwndid, % Lang["Modify"] %Gui_G%() Gui, Add, Text, x+30, % Lang["Comment"] Gui, Add, Edit, x+5 yp-2 w150 vComment Gui, Add, Button, x+30 yp-3 vSplitAdd Hwndid, % Lang["SplitAdd"] %Gui_G%() Gui, Add, Button, x+10 vAllAdd Hwndid, % Lang["AllAdd"] %Gui_G%() Gui, Add, Button, x+10 wp vOK Hwndid, % Lang["OK"] %Gui_G%() Gui, Add, Button, x+10 wp vCancel gCancel, % Lang["Cancel"] Gui, Add, Button, xm vBind0 Hwndid, % Lang["Bind0"] %Gui_G%() Gui, Add, Button, x+15 vBind1 Hwndid, % Lang["Bind1"] %Gui_G%() Gui, Add, Button, x+15 vBind2 Hwndid, % Lang["Bind2"] %Gui_G%() Gui, Add, Button, x+15 vBind3 Hwndid, % Lang["Bind3"] %Gui_G%() Gui, Add, Button, x+15 vBind4 Hwndid, % Lang["Bind4"] %Gui_G%() Gui, Show, Hide, % Lang["3"] return Case "MakeMainWindow": Gui, FindText_Main: New Gui, +AlwaysOnTop -DPIScale Gui, Margin, 15, 15 Gui, Color, %WindowColor% Gui, Font, s12, Verdana Gui, Add, Text, xm, % Lang["NowHotkey"] Gui, Add, Edit, x+5 w200 vNowHotkey ReadOnly Gui, Add, Hotkey, x+5 w200 vSetHotkey1 Gui, Add, DDL, x+5 w180 vSetHotkey2 , % "||F1|F2|F3|F4|F5|F6|F7|F8|F9|F10|F11|F12|LWin|MButton" . "|ScrollLock|CapsLock|Ins|Esc|BS|Del|Tab|Home|End|PgUp|PgDn" . "|NumpadDot|NumpadSub|NumpadAdd|NumpadDiv|NumpadMult" Gui, Add, GroupBox, xm y+0 w280 h55 vMyGroup cBlack Gui, Add, Text, xp+15 yp+20 Section, % Lang["Myww"] ": " Gui, Add, Text, x+0 w60, %ww% Gui, Add, UpDown, vMyww Range1-100, %ww% Gui, Add, Text, x+15 ys, % Lang["Myhh"] ": " Gui, Add, Text, x+0 w60, %hh% Gui, Add, UpDown, vMyhh Hwndid Range1-100, %hh% GuiControlGet, p, Pos, %id% GuiControl, Move, MyGroup, % "w" (pX+pW) " h" (pH+30) x:=pX+pW+15*2 Gui, Add, Button, x%x% ys-8 w150 vApply Hwndid, % Lang["Apply"] %Gui_G%() Gui, Add, Checkbox, x+30 ys Checked vAddFunc, % Lang["AddFunc"] " FindText()" Gui, Add, Button, xm y+18 w144 vCutL2 Hwndid, % Lang["CutL2"] %Gui_G%() Gui, Add, Button, x+0 wp vCutR2 Hwndid, % Lang["CutR2"] %Gui_G%() Gui, Add, Button, x+0 wp vCutU2 Hwndid, % Lang["CutU2"] %Gui_G%() Gui, Add, Button, x+0 wp vCutD2 Hwndid, % Lang["CutD2"] %Gui_G%() Gui, Add, Button, x+0 wp vUpdate Hwndid, % Lang["Update"] %Gui_G%() Gui, Font, s6 bold, Verdana Gui, Add, Edit, xm y+10 w720 r20 vMyPic -Wrap Gui, Font, s12 norm, Verdana Gui, Add, Button, xm w240 vCapture Hwndid, % Lang["Capture"] %Gui_G%() Gui, Add, Button, x+0 wp vTest Hwndid, % Lang["Test"] %Gui_G%() Gui, Add, Button, x+0 wp vCopy Hwndid, % Lang["Copy"] %Gui_G%() Gui, Add, Button, xm y+0 wp vCaptureS Hwndid, % Lang["CaptureS"] %Gui_G%() Gui, Add, Button, x+0 wp vGetRange Hwndid, % Lang["GetRange"] %Gui_G%() Gui, Add, Button, x+0 wp vTestClip Hwndid, % Lang["TestClip"] %Gui_G%() Gui, Font, s12 cBlue, Verdana Gui, Add, Edit, xm w720 h350 vscr Hwndhscr -Wrap HScroll Gui, Show, Hide, % Lang["4"] return Case "Capture","CaptureS": Critical Gui, FindText_Main: +Hwndid if (show_gui:=(WinExist()=id)) { WinMinimize Gui, FindText_Main: Hide } ShowScreenShot:=InStr(cmd,"CaptureS") if (ShowScreenShot) { f:=%Gui_%("SelectPic") if (f="") or !FileExist(f) { if (show_gui) { Gui, FindText_Main: Show GuiControl, FindText_Main: Focus, scr } Exit } FindText.ShowPic(f) } ;---------------------- Gui, FindText_HotkeyIf: New, -Caption +ToolWindow +E0x80000 Gui, Show, NA x0 y0 w0 h0, FindText_HotkeyIf Hotkey, IfWinExist, FindText_HotkeyIf Hotkey, *RButton, %Gui_Off%, On UseErrorLevel ListLines, % (lls:=A_ListLines)?"Off":"Off" CoordMode, Mouse KeyWait, RButton KeyWait, Ctrl w:=ww, h:=hh, oldx:=oldy:="", r:=StrSplit(Lang["5"],"|") if (!show_gui) w:=20, h:=8 Loop { Sleep, 50 MouseGetPos, x, y, Bind_ID if (!show_gui) { w:=x<=1 ? w-1 : x>=A_ScreenWidth-2 ? w+1:w h:=y<=1 ? h-1 : y>=A_ScreenHeight-2 ? h+1:h w:=(w<1 ? 1:w), h:=(h<1 ? 1:h) } %Gui_%("Mini_Show") if (oldx=x and oldy=y) Continue oldx:=x, oldy:=y ToolTip, % r.1 " : " x "," y "`n" r.2 } Until GetKeyState("RButton","P") or GetKeyState("Ctrl","P") KeyWait, RButton KeyWait, Ctrl px:=x, py:=y, oldx:=oldy:="" Loop { Sleep, 50 %Gui_%("Mini_Show") MouseGetPos, x1, y1 if (oldx=x1 and oldy=y1) Continue oldx:=x1, oldy:=y1 ToolTip, % r.1 " : " x "," y "`n" r.2 } Until GetKeyState("RButton","P") or GetKeyState("Ctrl","P") KeyWait, RButton KeyWait, Ctrl ToolTip %Gui_%("Mini_Hide") ListLines, %lls% Hotkey, *RButton, %Gui_Off%, Off UseErrorLevel Hotkey, IfWinExist Gui, FindText_HotkeyIf: Destroy if (ShowScreenShot) FindText.ShowPic() if (!show_gui) return [px-w, py-h, px+w, py+h] ;----------------------- %Gui_%("getcors", !ShowScreenShot) %Gui_%("Reset") Gui, FindText_Capture: Default Loop, 71 GuiControl,, % C_[71*25+A_Index], 0 Loop, 6 GuiControl,, Edit%A_Index% GuiControl,, Modify, % Modify:=0 GuiControl,, MultiColor, % MultiColor:=0 GuiControl,, GrayDiff, 50 GuiControl, Focus, Gray2Two GuiControl, +Default, Gray2Two Gui, Show, Center Event:=Result:="" DetectHiddenWindows, Off Critical, Off Gui, +LastFound WinWaitClose, % "ahk_id " WinExist() Critical ToolTip Gui, FindText_Main: Default ;-------------------------------- if (cors.bind!="") { WinGetTitle, tt, ahk_id %Bind_ID% WinGetClass, tc, ahk_id %Bind_ID% tt:=Trim(SubStr(tt,1,30) (tc ? " ahk_class " tc:"")) tt:=StrReplace(RegExReplace(tt,"[;``]","``$0"),"""","""""") Result:="`nSetTitleMatchMode, 2`nid:=WinExist(""" tt """)" . "`nFindText.BindWindow(id" (cors.bind=0 ? "":"," cors.bind) . ") `; " Lang["6"] " FindText.BindWindow(0)`n`n" Result } if (Event="OK") { if (!A_IsCompiled) { FileRead, s, %A_LineFile% s:=SubStr(s, s~="i)\n[;=]+ Copy The") } else s:="" GuiControl,, scr, % Result "`n" s if !InStr(Result,"##") GuiControl,, MyPic, % Trim(FindText.ASCII(Result),"`n") Result:=s:="" } else if (Event="SplitAdd") or (Event="AllAdd") { GuiControlGet, s,, scr i:=j:=0, r:="<[^>\n]*>[^$\n]+\$[\w+/,.\-]+" While j:=RegExMatch(s,r,"",j+1) i:=InStr(s,"`n",0,j) GuiControl,, scr, % SubStr(s,1,i) . Result . SubStr(s,i+1) if !InStr(Result,"##") GuiControl,, MyPic, % Trim(FindText.ASCII(Result),"`n") Result:=s:="" } ;---------------------- Gui, Show GuiControl, Focus, scr return Case "SelectPic": Gui, FindText_SelectPic: +LastFoundExist IfWinExist return Pics:=[], Names:=[], s:="" Loop, Files, % A_Temp "\Ahk_ScreenShot\*.bmp" Pics.Push(LoadPicture(v:=A_LoopFileFullPath, "w800 h500")) , Names.Push(v), s.="|" RegExReplace(v,"i)^.*\\|\.bmp$") if !Pics.Length() { Pics:="", Names:="" SetTimer, %Gui_ToolTip%, Off ToolTip MsgBox, 4096, Tip, % "`n" Lang["15"] " !`n", 3 return } Gui, FindText_SelectPic: New Gui, +LastFound +AlwaysOnTop -DPIScale Gui, Margin, 15, 15 Gui, Font, s12, Verdana Gui, Add, Pic, HwndhPic w800 h500 +Border, % "HBITMAP:*" Pics.1 Gui, Add, ListBox, % "x+15 w120 hp vSelectBox Hwndid" . " AltSubmit 0x100 Choose1", % Trim(s,"|") %Gui_G%() Gui, Add, Button, xm w223 vOK2 Hwndid Default, % Lang["OK2"] %Gui_G%() Gui, Add, Button, x+15 wp vCancel2 gCancel, % Lang["Cancel2"] Gui, Add, Button, x+15 wp vClearAll Hwndid, % Lang["ClearAll"] %Gui_G%() Gui, Add, Button, x+15 wp vOpenDir Hwndid, % Lang["OpenDir"] %Gui_G%() GuiControl, Focus, SelectBox Gui, Show,, Select ScreenShot ;----------------------- DetectHiddenWindows, Off Critical, Off file:="" WinWaitClose, % "ahk_id " WinExist() Critical Gui, Destroy Loop, % Pics.Length() DllCall("DeleteObject", "Ptr",Pics[A_Index]) Pics:="", Names:="" return file Case "SelectBox": Gui, FindText_SelectPic: Default GuiControlGet, SelectBox if (Pics[SelectBox]) GuiControl,, %hPic%, % "HBITMAP:*" Pics[SelectBox] return Case "OK2": GuiControlGet, SelectBox file:=Names[SelectBox] Gui, FindText_SelectPic: Hide return Case "ClearAll": FileDelete, % A_Temp "\Ahk_ScreenShot\*.bmp" Gui, FindText_SelectPic: Hide return Case "OpenDir": Run, % A_Temp "\Ahk_ScreenShot\" return Case "Mini_Show": Gui, FindText_Mini_4: +LastFoundExist IfWinNotExist { Loop, 4 { i:=A_Index Gui, FindText_Mini_%i%: +AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000 Gui, FindText_Mini_%i%: Show, Hide, Mini } } d:=2, w:=w<0 ? 0:w, h:=h<0 ? 0:h, c:=A_MSec<500 ? "Red":"Blue" Loop, 4 { i:=A_Index x1:=Floor(i=3 ? x+w+1 : x-w-d) y1:=Floor(i=4 ? y+h+1 : y-h-d) w1:=Floor(i=1 or i=3 ? d : 2*(w+d)+1) h1:=Floor(i=2 or i=4 ? d : 2*(h+d)+1) Gui, FindText_Mini_%i%: Color, %c% Gui, FindText_Mini_%i%: Show, NA x%x1% y%y1% w%w1% h%h1% } return Case "Mini_Hide": Gui, FindText_Mini_4: +Hwndid Loop, 4 Gui, FindText_Mini_%A_Index%: Destroy WinWaitClose, ahk_id %id%,, 3 return Case "getcors": FindText.xywh2xywh(px-ww,py-hh,2*ww+1,2*hh+1,x,y,w,h) if (w<1 or h<1) return SetBatchLines, % (bch:=A_BatchLines)?"-1":"-1" if (arg1) FindText.ScreenShot() cors:=[], gray:=[], k:=0 ListLines, % (lls:=A_ListLines)?"Off":"Off" Loop, %nH% { j:=py-hh+A_Index-1, i:=px-ww Loop, %nW% cors[++k]:=c:=FindText.GetColor(i++,j,0) , gray[k]:=(((c>>16)&0xFF)*38+((c>>8)&0xFF)*75+(c&0xFF)*15)>>7 } ListLines, %lls% cors.CutLeft:=Abs(px-ww-x) cors.CutRight:=Abs(px+ww-(x+w-1)) cors.CutUp:=Abs(py-hh-y) cors.CutDown:=Abs(py+hh-(y+h-1)) SetBatchLines, %bch% return Case "GetRange": Critical Gui, FindText_Main: +Hwndid if (show_gui:=(WinExist()=id)) Gui, FindText_Main: Hide ;--------------------- Gui, FindText_GetRange: New Gui, +LastFound +AlWaysOnTop +ToolWindow -Caption -DPIScale +E0x08000000 Gui, Color, White WinSet, Transparent, 10 FindText.xywh2xywh(0,0,0,0,0,0,0,0,x,y,w,h) Gui, Show, NA x%x% y%y% w%w% h%h%, GetRange ;--------------------- Gui, FindText_HotkeyIf: New, -Caption +ToolWindow +E0x80000 Gui, Show, NA x0 y0 w0 h0, FindText_HotkeyIf Hotkey, IfWinExist, FindText_HotkeyIf Hotkey, *LButton, %Gui_Off%, On UseErrorLevel ListLines, % (lls:=A_ListLines)?"Off":"Off" CoordMode, Mouse KeyWait, LButton KeyWait, Ctrl oldx:=oldy:="", r:=Lang["7"] Loop { Sleep, 50 MouseGetPos, x, y if (oldx=x and oldy=y) Continue oldx:=x, oldy:=y ToolTip, %r% } Until GetKeyState("LButton","P") or GetKeyState("Ctrl","P") px:=x, py:=y, oldx:=oldy:="" Loop { Sleep, 50 MouseGetPos, x, y w:=Abs(px-x)//2, h:=Abs(py-y)//2, x:=(px+x)//2, y:=(py+y)//2 %Gui_%("Mini_Show") if (oldx=x and oldy=y) Continue oldx:=x, oldy:=y ToolTip, %r% } Until !(GetKeyState("LButton","P") or GetKeyState("Ctrl","P")) ToolTip %Gui_%("Mini_Hide") ListLines, %lls% Hotkey, *LButton, %Gui_Off%, Off UseErrorLevel Hotkey, IfWinExist Gui, FindText_HotkeyIf: Destroy Gui, FindText_GetRange: Destroy Clipboard:=p:=(x-w) ", " (y-h) ", " (x+w) ", " (y+h) if (!show_gui) return StrSplit(p, ",", " ") ;--------------------- Gui, FindText_Main: Default GuiControlGet, s,, scr if RegExMatch(s, "i)(=\s*FindText\()([^,]*,){4}", r) { s:=StrReplace(s, r, r1 . p ",", 0, 1) GuiControl,, scr, %s% } Gui, Show return Case "Test","TestClip": Gui, FindText_Main: Default Gui, +LastFound WinMinimize Gui, Hide DetectHiddenWindows, Off WinWaitClose, % "ahk_id " WinExist() Sleep, 100 ;---------------------- if (cmd="Test") GuiControlGet, s,, scr else s:=Clipboard if (!A_IsCompiled) and InStr(s,"MCode(") and (cmd="Test") { s:="`n#NoEnv`nMenu, Tray, Click, 1`n" s "`nExitApp`n" Thread:= new FindText.Thread(s) DetectHiddenWindows, On WinWait, % "ahk_class AutoHotkey ahk_pid " Thread.pid,, 3 if (!ErrorLevel) WinWaitClose,,, 30 Thread:="" ; kill the Thread } else { Gui, +OwnDialogs t:=A_TickCount, n:=150000 , RegExMatch(s,"<[^>\n]*>[^$\n]+\$[\w+/,.\-]+",k) , v:=FindText.FindText(-n, -n, n, n, 0, 0, k) , X:=v.1.x, Y:=v.1.y, Comment:=v.1.id r:=StrSplit(Lang["8"],"|") MsgBox, 4096, Tip, % r.1 ":`t" Round(v.MaxIndex()) "`n`n" . r.2 ":`t" (A_TickCount-t) " " r.3 "`n`n" . r.4 ":`t" X ", " Y "`n`n" . r.5 ":`t" (v ? r.6 " ! " Comment : r.7 " !"), 3 for i,j in v if (i<=2) FindText.MouseTip(j.x, j.y) v:="" } ;---------------------- Gui, Show GuiControl, Focus, scr return Case "Copy": Gui, FindText_Main: Default ControlGet, s, Selected,,, ahk_id %hscr% if (s="") { GuiControlGet, s,, scr GuiControlGet, r,, AddFunc if (r != 1) s:=RegExReplace(s,"\n\K[\s;=]+ Copy The[\s\S]*") } Clipboard:=RegExReplace(s,"\R","`r`n") ;---------------------- Gui, Hide Sleep, 100 Gui, Show GuiControl, Focus, scr return Case "Apply": Gui, FindText_Main: Default GuiControlGet, NowHotkey GuiControlGet, SetHotkey1 GuiControlGet, SetHotkey2 if (NowHotkey!="") Hotkey, *%NowHotkey%,, Off UseErrorLevel k:=SetHotkey1!="" ? SetHotkey1 : SetHotkey2 if (k!="") Hotkey, *%k%, %Gui_ScreenShot%, On UseErrorLevel GuiControl,, NowHotkey, %k% GuiControl,, SetHotkey1 GuiControl, Choose, SetHotkey2, 0 ;------------------------ GuiControlGet, Myww GuiControlGet, Myhh if (Myww!=ww or Myhh!=hh) { nW:=71, dx:=dy:=0 Loop, % 71*25 k:=A_Index, c:=WindowColor, %Gui_%("SetColor") ww:=Myww, hh:=Myhh, nW:=2*ww+1, nH:=2*hh+1 i:=nW>71, j:=nH>25 Gui, FindText_Capture: Default GuiControl, Enable%i%, MySlider1 GuiControl, Enable%j%, MySlider2 GuiControl,, MySlider1, % MySlider1:=0 GuiControl,, MySlider2, % MySlider2:=0 } return Case "ScreenShot": Critical f:=A_Temp "\Ahk_ScreenShot" if !InStr(r:=FileExist(f), "D") { if (r) { FileSetAttrib, -R, %f% FileDelete, %f% } FileCreateDir, %f% } Loop f:=A_Temp "\Ahk_ScreenShot\" Format("{:03d}",A_Index) ".bmp" Until !FileExist(f) FindText.SavePic(f) Gui, FindText_Tip: New ; WS_EX_NOACTIVATE:=0x08000000, WS_EX_TRANSPARENT:=0x20 Gui, +LastFound +AlwaysOnTop +ToolWindow -Caption -DPIScale +E0x08000020 Gui, Color, Yellow Gui, Font, cRed s48 bold Gui, Add, Text,, % Lang["9"] WinSet, Transparent, 200 Gui, Show, NA y0, ScreenShot Tip Sleep, 100 Gui, Destroy return Case "Bind0","Bind1","Bind2","Bind3","Bind4": Critical FindText.BindWindow(Bind_ID, bind_mode:=SubStr(cmd,0)) Gui, FindText_HotkeyIf: New, -Caption +ToolWindow +E0x80000 Gui, Show, NA x0 y0 w0 h0, FindText_HotkeyIf Hotkey, IfWinExist, FindText_HotkeyIf Hotkey, *RButton, %Gui_Off%, On UseErrorLevel ListLines, % (lls:=A_ListLines)?"Off":"Off" CoordMode, Mouse KeyWait, RButton KeyWait, Ctrl oldx:=oldy:="" Loop { Sleep, 50 MouseGetPos, x, y if (oldx=x and oldy=y) Continue oldx:=x, oldy:=y ;--------------- px:=x, py:=y, %Gui_%("getcors",1) %Gui_%("Reset"), r:=StrSplit(Lang["10"],"|") ToolTip, % r.1 " : " x "," y "`n" r.2 } Until GetKeyState("RButton","P") or GetKeyState("Ctrl","P") KeyWait, RButton KeyWait, Ctrl ToolTip ListLines, %lls% Hotkey, *RButton, %Gui_Off%, Off UseErrorLevel Hotkey, IfWinExist Gui, FindText_HotkeyIf: Destroy FindText.BindWindow(0), cors.bind:=bind_mode return Case "MySlider1","MySlider2": Thread, Priority, 10 Critical, Off dx:=nW>71 ? Round((nW-71)*MySlider1/100) : 0 dy:=nH>25 ? Round((nH-25)*MySlider2/100) : 0 if (oldx=dx and oldy=dy) return oldx:=dx, oldy:=dy, k:=0 Loop, % nW*nH c:=(!show[++k] ? WindowColor : bg="" ? cors[k] : ascii[k] ? "Black":"White"), %Gui_%("SetColor") if (cmd="MySlider2") return Loop, 71 GuiControl,, % C_[71*25+A_Index], 0 Loop, % nW { i:=A_Index-dx if (i>=1 && i<=71 && show[nW*nH+A_Index]) GuiControl,, % C_[71*25+i], 100 } return Case "Reset": show:=[], ascii:=[], bg:="" CutLeft:=CutRight:=CutUp:=CutDown:=k:=0 Loop, % nW*nH show[++k]:=1, c:=cors[k], %Gui_%("SetColor") Loop, % cors.CutLeft %Gui_%("CutL") Loop, % cors.CutRight %Gui_%("CutR") Loop, % cors.CutUp %Gui_%("CutU") Loop, % cors.CutDown %Gui_%("CutD") return Case "SetColor": if (nW=71 && nH=25) tk:=k else { tx:=Mod(k-1,nW)-dx, ty:=(k-1)//nW-dy if (tx<0 || tx>=71 || ty<0 || ty>=25) return tk:=ty*71+tx+1 } c:=c="Black" ? 0x000000 : c="White" ? 0xFFFFFF : ((c&0xFF)<<16)|(c&0xFF00)|((c&0xFF0000)>>16) SendMessage, 0x2001, 0, c,, % "ahk_id " . C_[tk] return Case "RepColor": show[k]:=1, c:=(bg="" ? cors[k] : ascii[k] ? "Black":"White"), %Gui_%("SetColor") return Case "CutColor": show[k]:=0, c:=WindowColor, %Gui_%("SetColor") return Case "RepL": if (CutLeft<=cors.CutLeft) or (bg!="" and InStr(color,"**") and CutLeft=cors.CutLeft+1) return k:=CutLeft-nW, CutLeft-- Loop, %nH% k+=nW, (A_Index>CutUp and A_Index<nH+1-CutDown ? %Gui_%("RepColor") : "") return Case "CutL": if (CutLeft+CutRight>=nW) return CutLeft++, k:=CutLeft-nW Loop, %nH% k+=nW, (A_Index>CutUp and A_Index<nH+1-CutDown ? %Gui_%("CutColor") : "") return Case "CutL3": Loop, 3 %Gui_%("CutL") return Case "RepR": if (CutRight<=cors.CutRight) or (bg!="" and InStr(color,"**") and CutRight=cors.CutRight+1) return k:=1-CutRight, CutRight-- Loop, %nH% k+=nW, (A_Index>CutUp and A_Index<nH+1-CutDown ? %Gui_%("RepColor") : "") return Case "CutR": if (CutLeft+CutRight>=nW) return CutRight++, k:=1-CutRight Loop, %nH% k+=nW, (A_Index>CutUp and A_Index<nH+1-CutDown ? %Gui_%("CutColor") : "") return Case "CutR3": Loop, 3 %Gui_%("CutR") return Case "RepU": if (CutUp<=cors.CutUp) or (bg!="" and InStr(color,"**") and CutUp=cors.CutUp+1) return k:=(CutUp-1)*nW, CutUp-- Loop, %nW% k++, (A_Index>CutLeft and A_Index<nW+1-CutRight ? %Gui_%("RepColor") : "") return Case "CutU": if (CutUp+CutDown>=nH) return CutUp++, k:=(CutUp-1)*nW Loop, %nW% k++, (A_Index>CutLeft and A_Index<nW+1-CutRight ? %Gui_%("CutColor") : "") return Case "CutU3": Loop, 3 %Gui_%("CutU") return Case "RepD": if (CutDown<=cors.CutDown) or (bg!="" and InStr(color,"**") and CutDown=cors.CutDown+1) return k:=(nH-CutDown)*nW, CutDown-- Loop, %nW% k++, (A_Index>CutLeft and A_Index<nW+1-CutRight ? %Gui_%("RepColor") : "") return Case "CutD": if (CutUp+CutDown>=nH) return CutDown++, k:=(nH-CutDown)*nW Loop, %nW% k++, (A_Index>CutLeft and A_Index<nW+1-CutRight ? %Gui_%("CutColor") : "") return Case "CutD3": Loop, 3 %Gui_%("CutD") return Case "Gray2Two": Gui, FindText_Capture: Default GuiControl, Focus, Threshold GuiControlGet, Threshold if (Threshold="") { pp:=[] Loop, 256 pp[A_Index-1]:=0 Loop, % nW*nH if (show[A_Index]) pp[gray[A_Index]]++ IP:=IS:=0 Loop, 256 k:=A_Index-1, IP+=k*pp[k], IS+=pp[k] Threshold:=Floor(IP/IS) Loop, 20 { LastThreshold:=Threshold IP1:=IS1:=0 Loop, % LastThreshold+1 k:=A_Index-1, IP1+=k*pp[k], IS1+=pp[k] IP2:=IP-IP1, IS2:=IS-IS1 if (IS1!=0 and IS2!=0) Threshold:=Floor((IP1/IS1+IP2/IS2)/2) if (Threshold=LastThreshold) Break } GuiControl,, Threshold, %Threshold% } Threshold:=Round(Threshold) color:="*" Threshold, k:=i:=0 Loop, % nW*nH { ascii[++k]:=v:=(gray[k]<=Threshold) if (show[k]) i:=(v?i+1:i-1), c:=(v?"Black":"White"), %Gui_%("SetColor") } bg:=i>0 ? "1":"0" return Case "GrayDiff2Two": Gui, FindText_Capture: Default GuiControlGet, GrayDiff if (GrayDiff="") { Gui, +OwnDialogs MsgBox, 4096, Tip, % "`n" Lang["11"] " !`n", 1 return } if (CutLeft=cors.CutLeft) %Gui_%("CutL") if (CutRight=cors.CutRight) %Gui_%("CutR") if (CutUp=cors.CutUp) %Gui_%("CutU") if (CutDown=cors.CutDown) %Gui_%("CutD") GrayDiff:=Round(GrayDiff) color:="**" GrayDiff, k:=i:=0 Loop, % nW*nH { j:=gray[++k]+GrayDiff , ascii[k]:=v:=( gray[k-1]>j or gray[k+1]>j or gray[k-nW]>j or gray[k+nW]>j or gray[k-nW-1]>j or gray[k-nW+1]>j or gray[k+nW-1]>j or gray[k+nW+1]>j ) if (show[k]) i:=(v?i+1:i-1), c:=(v?"Black":"White"), %Gui_%("SetColor") } bg:=i>0 ? "1":"0" return Case "Color2Two","ColorPos2Two": Gui, FindText_Capture: Default GuiControlGet, c,, SelColor if (c="") { Gui, +OwnDialogs MsgBox, 4096, Tip, % "`n" Lang["12"] " !`n", 1 return } UsePos:=(cmd="ColorPos2Two") ? 1:0 GuiControlGet, n,, Similar1 n:=Round(n/100,2), color:=c "@" n , n:=Floor(512*9*255*255*(1-n)*(1-n)), k:=i:=0 , rr:=(c>>16)&0xFF, gg:=(c>>8)&0xFF, bb:=c&0xFF Loop, % nW*nH { c:=cors[++k], r:=((c>>16)&0xFF)-rr , g:=((c>>8)&0xFF)-gg, b:=(c&0xFF)-bb, j:=r+rr+rr , ascii[k]:=v:=((1024+j)*r*r+2048*g*g+(1534-j)*b*b<=n) if (show[k]) i:=(v?i+1:i-1), c:=(v?"Black":"White"), %Gui_%("SetColor") } bg:=i>0 ? "1":"0" return Case "ColorDiff2Two": Gui, FindText_Capture: Default GuiControlGet, c,, SelColor if (c="") { Gui, +OwnDialogs MsgBox, 4096, Tip, % "`n" Lang["12"] " !`n", 1 return } GuiControlGet, dR GuiControlGet, dG GuiControlGet, dB rr:=(c>>16)&0xFF, gg:=(c>>8)&0xFF, bb:=c&0xFF , n:=Format("{:06X}",(dR<<16)|(dG<<8)|dB) , color:=StrReplace(c "-" n,"0x"), k:=i:=0 Loop, % nW*nH { c:=cors[++k], r:=(c>>16)&0xFF, g:=(c>>8)&0xFF , b:=c&0xFF, ascii[k]:=v:=(Abs(r-rr)<=dR and Abs(g-gg)<=dG and Abs(b-bb)<=dB) if (show[k]) i:=(v?i+1:i-1), c:=(v?"Black":"White"), %Gui_%("SetColor") } bg:=i>0 ? "1":"0" return Case "Modify": GuiControlGet, Modify return Case "MultiColor": GuiControlGet, MultiColor Result:="" ToolTip return Case "Undo": Result:=RegExReplace(Result,",[^/]+/[^/]+/[^/]+$") ToolTip, % Trim(Result,"/,") return Case "Similar1": GuiControl, FindText_Capture:, Similar2, %Similar1% return Case "Similar2": GuiControl, FindText_Capture:, Similar1, %Similar2% return Case "GetTxt": txt:="" if (bg="") return ListLines, % (lls:=A_ListLines)?"Off":"Off" k:=0 Loop, %nH% { v:="" Loop, %nW% v.=!show[++k] ? "" : ascii[k] ? "1":"0" txt.=v="" ? "" : v "`n" } ListLines, %lls% return Case "Auto": %Gui_%("GetTxt") if (txt="") { Gui, FindText_Capture: +OwnDialogs MsgBox, 4096, Tip, % "`n" Lang["13"] " !`n", 1 return } While InStr(txt,bg) { if (txt~="^" bg "+\n") txt:=RegExReplace(txt,"^" bg "+\n"), %Gui_%("CutU") else if !(txt~="m`n)[^\n" bg "]$") txt:=RegExReplace(txt,"m`n)" bg "$"), %Gui_%("CutR") else if (txt~="\n" bg "+\n$") txt:=RegExReplace(txt,"\n\K" bg "+\n$"), %Gui_%("CutD") else if !(txt~="m`n)^[^\n" bg "]") txt:=RegExReplace(txt,"m`n)^" bg), %Gui_%("CutL") else Break } txt:="" return Case "OK","SplitAdd","AllAdd": Gui, FindText_Capture: Default Gui, +OwnDialogs %Gui_%("GetTxt") if (txt="") and (!MultiColor) { MsgBox, 4096, Tip, % "`n" Lang["13"] " !`n", 1 return } if InStr(color,"@") and (UsePos) and (!MultiColor) { r:=StrSplit(color,"@") k:=i:=j:=0 Loop, % nW*nH { if (!show[++k]) Continue i++ if (k=cors.SelPos) { j:=i Break } } if (j=0) { MsgBox, 4096, Tip, % "`n" Lang["12"] " !`n", 1 return } color:="#" (j-1) "@" r.2 } GuiControlGet, Comment if (cmd="SplitAdd") and (!MultiColor) { if InStr(color,"#") { MsgBox, 4096, Tip, % Lang["14"], 3 return } bg:=StrLen(StrReplace(txt,"0")) > StrLen(StrReplace(txt,"1")) ? "1":"0" s:="", i:=0, k:=nW*nH+1+CutLeft Loop, % w:=nW-CutLeft-CutRight { i++ if (!show[k++] and A_Index<w) Continue i:=Format("{:d}",i) v:=RegExReplace(txt,"m`n)^(.{" i "}).*","$1") txt:=RegExReplace(txt,"m`n)^.{" i "}"), i:=0 While InStr(v,bg) { if (v~="^" bg "+\n") v:=RegExReplace(v,"^" bg "+\n") else if !(v~="m`n)[^\n" bg "]$") v:=RegExReplace(v,"m`n)" bg "$") else if (v~="\n" bg "+\n$") v:=RegExReplace(v,"\n\K" bg "+\n$") else if !(v~="m`n)^[^\n" bg "]") v:=RegExReplace(v,"m`n)^" bg) else Break } if (v!="") { v:=Format("{:d}",InStr(v,"`n")-1) "." FindText.bit2base64(v) s.="`nText.=""|<" SubStr(Comment,1,1) ">" color "$" v """`n" Comment:=SubStr(Comment, 2) } } Event:=cmd, Result:=s Gui, Hide return } if (!MultiColor) txt:=Format("{:d}",InStr(txt,"`n")-1) "." FindText.bit2base64(txt) else { GuiControlGet, dRGB r:=StrSplit(Trim(StrReplace(Result,",","/"),"/"),"/") , x:=r.1, y:=r.2, s:="", i:=1 Loop, % r.MaxIndex()//3 s.="," (r[i++]-x) "/" (r[i++]-y) "/" r[i++] txt:=SubStr(s,2), color:="##" dRGB } s:="`nText.=""|<" Comment ">" color "$" txt """`n" if (cmd="AllAdd") { Event:=cmd, Result:=s Gui, Hide return } x:=px-ww+CutLeft+(nW-CutLeft-CutRight)//2 y:=py-hh+CutUp+(nH-CutUp-CutDown)//2 s:=StrReplace(s, "Text.=", "Text:="), r:=StrSplit(Lang["8"],"|") s:="`; #Include <FindText>`n" . "`n t1:=A_TickCount, X:=Y:=""""`n" s . "`n if (ok:=FindText(" x "-150000, " y "-150000, " x "+150000, " y "+150000, 0, 0, Text))" . "`n {" . "`n CoordMode, Mouse" . "`n X:=ok.1.x, Y:=ok.1.y, Comment:=ok.1.id" . "`n `; Click, `%X`%, `%Y`%" . "`n }`n" . "`n MsgBox, 4096, Tip, `% """ r.1 ":``t"" Round(ok.MaxIndex())" . "`n . ""``n``n" r.2 ":``t"" (A_TickCount-t1) "" " r.3 """" . "`n . ""``n``n" r.4 ":``t"" X "", "" Y" . "`n . ""``n``n" r.5 ":``t"" (ok ? """ r.6 " !"" : """ r.7 " !"")`n" . "`n for i,v in ok" . "`n if (i<=2)" . "`n FindText.MouseTip(ok[i].x, ok[i].y)`n" Event:=cmd, Result:=s Gui, Hide return Case "KeyDown": Critical if (A_Gui="FindText_Main" && A_GuiControl="scr") SetTimer, %Gui_ShowPic%, -150 return Case "ShowPic": ControlGet, i, CurrentLine,,, ahk_id %hscr% ControlGet, s, Line, %i%,, ahk_id %hscr% GuiControl, FindText_Main:, MyPic, % Trim(FindText.ASCII(s),"`n") return Case "LButtonDown": Critical if (A_Gui!="FindText_Capture") return %Gui_%("KeyDown") MouseGetPos,,,, k2, 2 if (k1:=Round(Cid_[k2]))<1 return Gui, FindText_Capture: Default if (k1>71*25) { GuiControlGet, k3,, %k2% GuiControl,, %k2%, % k3 ? 0:100 show[nW*nH+(k1-71*25)+dx]:=(!k3) return } k2:=Mod(k1-1,71)+dx, k3:=(k1-1)//71+dy if (k2>=nW || k3>=nH) return k1:=k, k:=k3*nW+k2+1, k2:=c if (MultiColor and show[k]) { c:="," Mod(k-1,nW) "/" k3 "/" . Format("{:06X}",cors[k]&0xFFFFFF) , Result.=InStr(Result,c) ? "":c ToolTip, % Trim(Result,"/,") } else if (Modify and bg!="" and show[k]) { c:=((ascii[k]:=!ascii[k]) ? "Black":"White") , %Gui_%("SetColor") } else { c:=cors[k], cors.SelPos:=k GuiControl,, SelGray, % gray[k] GuiControl,, SelColor, % Format("0x{:06X}",c&0xFFFFFF) GuiControl,, SelR, % (c>>16)&0xFF GuiControl,, SelG, % (c>>8)&0xFF GuiControl,, SelB, % c&0xFF } k:=k1, c:=k2 return Case "MouseMove": static PrevControl:="" if (PrevControl!=A_GuiControl) { PrevControl:=A_GuiControl SetTimer, %Gui_ToolTip%, % PrevControl ? -500 : "Off" SetTimer, %Gui_ToolTipOff%, % PrevControl ? -5500 : "Off" ToolTip } return Case "ToolTip": MouseGetPos,,, _TT IfWinExist, ahk_id %_TT% ahk_class AutoHotkeyGUI ToolTip, % Tip_Text[PrevControl ""] return Case "ToolTipOff": ToolTip return Case "CutL2","CutR2","CutU2","CutD2": Gui, FindText_Main: Default GuiControlGet, s,, MyPic s:=Trim(s,"`n") . "`n", v:=SubStr(cmd,4,1) if (v="U") s:=RegExReplace(s,"^[^\n]+\n") else if (v="D") s:=RegExReplace(s,"[^\n]+\n$") else if (v="L") s:=RegExReplace(s,"m`n)^[^\n]") else if (v="R") s:=RegExReplace(s,"m`n)[^\n]$") GuiControl,, MyPic, % Trim(s,"`n") return Case "Update": Gui, FindText_Main: Default GuiControl, Focus, scr ControlGet, i, CurrentLine,,, ahk_id %hscr% ControlGet, s, Line, %i%,, ahk_id %hscr% if !RegExMatch(s,"(<[^>]*>[^$]+\$)\d+\.[\w+/]+",r) return GuiControlGet, v,, MyPic v:=Trim(v,"`n") . "`n", w:=Format("{:d}",InStr(v,"`n")-1) v:=StrReplace(StrReplace(v,"0","1"),"_","0") s:=StrReplace(s,r,r1 . w "." FindText.bit2base64(v)) v:="{End}{Shift Down}{Home}{Shift Up}{Del}" ControlSend,, %v%, ahk_id %hscr% Control, EditPaste, %s%,, ahk_id %hscr% ControlSend,, {Home}, ahk_id %hscr% return Case "Load_Language_Text": s= ( Myww = 宽度 = 调整捕获范围的宽度 Myhh = 高度 = 调整捕获范围的高度 AddFunc = 附加 = 将 FindText() 函数代码一起复制 NowHotkey = 截屏热键 = 当前的截屏热键 SetHotkey1 = = 第一优先级的截屏热键 SetHotkey2 = = 第二优先级的截屏热键 Apply = 应用 = 应用新的截屏热键和调整后的捕获范围值 CutU2 = 上删 = 裁剪下面编辑框中文字的上边缘 CutL2 = 左删 = 裁剪下面编辑框中文字的左边缘 CutR2 = 右删 = 裁剪下面编辑框中文字的右边缘 CutD2 = 下删 = 裁剪下面编辑框中文字的下边缘 Update = 更新 = 更新下面编辑框中文字到代码行中 GetRange = 获取屏幕范围 = 获取屏幕范围到剪贴板并替换代码中的范围 TestClip = 测试复制的文字 = 测试复制到剪贴板的文字代码 Capture = 抓图 = 开始屏幕抓图 CaptureS = 截屏抓图 = 先恢复上一次的截屏到屏幕再开始抓图 Test = 测试 = 测试生成的代码是否可以找字成功 Copy = 复制 = 复制代码到剪贴板 Reset = 重读 = 重新读取原来的彩色图像 SplitAdd = 分割添加 = 使用黄色的标签来分割图像为单个的图像数据,添加到旧代码中 AllAdd = 整体添加 = 将文字数据整体添加到旧代码中 OK = 确定 = 生成全新的代码替换旧代码 Cancel = 取消 = 关闭窗口不做任何事 Gray2Two = 灰度阈值二值化 = 灰度小于阈值的为黑色其余白色 GrayDiff2Two = 灰度差值二值化 = 某点与周围灰度之差大于差值的为黑色其余白色 Color2Two = 颜色相似二值化 = 指定颜色及相似色为黑色其余白色 ColorPos2Two = 颜色位置二值化 = 指定颜色及相似色为黑色其余白色,但是记录该色的位置 ColorDiff2Two = 颜色分量二值化 = 指定颜色及颜色分量小于允许值的为黑色其余白色 SelGray = 灰度 = 选定颜色的灰度值 (0-255) SelColor = 颜色 = 选定颜色的RGB颜色值 SelR = 红 = 选定颜色的红色分量 SelG = 绿 = 选定颜色的绿色分量 SelB = 蓝 = 选定颜色的蓝色分量 RepU = -上 = 撤销裁剪上边缘1个像素 CutU = 上 = 裁剪上边缘1个像素 CutU3 = 上3 = 裁剪上边缘3个像素 RepL = -左 = 撤销裁剪左边缘1个像素 CutL = 左 = 裁剪左边缘1个像素 CutL3 = 左3 = 裁剪左边缘3个像素 Auto = 自动 = 二值化之后自动裁剪空白边缘 RepR = -右 = 撤销裁剪右边缘1个像素 CutR = 右 = 裁剪右边缘1个像素 CutR3 = 右3 = 裁剪右边缘3个像素 RepD = -下 = 撤销裁剪下边缘1个像素 CutD = 下 = 裁剪下边缘1个像素 CutD3 = 下3 = 裁剪下边缘3个像素 Modify = 修改 = 二值化后允许修改黑白点 MultiColor = 多色查找 = 鼠标选择多种颜色,之后点击“确定”按钮 Undo = 撤销 = 撤销上一次选择的颜色 Comment = 识别文字 = 识别文本 (包含在<>中),分割添加时也会分解成单个文字 Threshold = 灰度阈值 = 灰度阈值 (0-255) GrayDiff = 灰度差值 = 灰度差值 (0-255) Similar1 = 相似度 = 与选定颜色的相似度 Similar2 = 相似度 = 与选定颜色的相似度 DiffR = 红 = 红色分量允许的偏差 (0-255) DiffG = 绿 = 绿色分量允许的偏差 (0-255) DiffB = 蓝 = 蓝色分量允许的偏差 (0-255) DiffRGB = 红/绿/蓝 = 多色查找时各分量允许的偏差 (0-255) Bind0 = 绑定窗口1 = 绑定窗口使用GetDCEx()获取后台窗口图像 Bind1 = 绑定窗口1+ = 绑定窗口使用GetDCEx()并修改窗口透明度 Bind2 = 绑定窗口2 = 绑定窗口使用PrintWindow()获取后台窗口图像 Bind3 = 绑定窗口2+ = 绑定窗口使用PrintWindow()并修改窗口透明度 Bind4 = 绑定窗口3 = 绑定窗口使用PrintWindow(,,3)获取后台窗口图像 OK2 = 确定 = 生成全新的代码替换旧代码 Cancel2 = 取消 = 关闭窗口不做任何事 ClearAll = 清空 = 清空所有保存的截图 OpenDir = 打开目录 = 打开保存屏幕截图的目录 1 = 查找文字工具 2 = 灰度阈值|灰度差值|颜色相似|颜色位置|颜色分量|多色查找 3 = 图像二值化及分割 4 = 抓图生成字库及找字代码 5 = 位置|先点击右键一次\n把鼠标移开\n再点击右键一次 6 = 解绑窗口使用 7 = 请用左键拖动范围\n坐标复制到剪贴板 8 = 找到|时间|毫秒|位置|结果|成功|失败 9 = 截屏成功 10 = 鼠标位置|穿透显示绑定窗口\n点击右键完成抓图 11 = 请先设定灰度差值 12 = 请先选择核心颜色 13 = 请先将图像二值化 14 = 不能用于颜色位置二值化模式, 因为分割后会导致位置错误 15 = 请先设置热键并使用热键抓取屏幕截图 ) Lang:=[], Tip_Text:=[] Loop, Parse, s, `n, `r if InStr(v:=A_LoopField, "=") r:=StrSplit(StrReplace(v,"\n","`n"), "=", "`t ") , Lang[r.1 ""]:=r.2, Tip_Text[r.1 ""]:=r.3 return } } } ;// Class End ;================= The End ================= ;
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)