屏幕截图的新用法

autoIt这个工具,我是尽量不用的,因为稳定性比较差,或者说比较难保证。但有个需求,感觉不用autoIt一类的工具,似乎没有更好的办法。

需求是这样的,城通网盘,因为vip的性价比实在不高,不想买,而免费用户,如果在网页上直接下载,稳定性很差,如果用它的客户端下载,虽然稳定性有提高,但速度仍然很低,而且只允许单线程单任务下载。不过前几天偶然发现一个方法,可以实现多任务下载,不过只能等一个任务下载完后,再手工添加新任务继续下载,而不能一下子添加多个任务。这样,就需要盯着下载进度,受不了,就想写个程序来实现。用autoIt的au3Info工具(类似Spy++)看了下,窗口的类型是chrome_widgetwin_1,没办法取它的子控件,看来只能用autoIt,根据屏幕坐标来实现自动操作了。

需要解决的主要是两个问题。一是如何识别一个任务下载完了,一是如何自动点击。后一个问题比较简单,就是用它自带的工具au3Record录制一下点击动作,稍微修改一下生成的脚本,就可以了。但前一个如何办?想了半天,最后想到截屏的办法。如果一个任务正在下载,界面上会显示下载任务的文件名称,下载速度,还有一个小小的电影胶片的图标。下载完后,这个下载任务就不显示了。于是,根据屏幕坐标,将这个电影胶片的图标截下来,保存到文件,然后定时检查该坐标区域是否还存在电影胶片的图标,如果不存在就说明下载完了,可以添加新任务了。后来发现取电影胶片的图标不合适,因为不同的文件类型,这个图标是不同的,就改用别的区域的截图。

查了下,有人写了个扩展库ImageSearch,有匹配图片的功能。下载后试了下,不work。边吃饭边考虑是什么问题,开始怀疑是缺少某些vc++的支持库,但忽然有了另外一个主意。可以先根据屏幕坐标把电影胶片的图标截下来保存到A文件,然后定时(比如每隔一分钟)用同样的坐标再次截屏,保存到B文件,然后将A文件的大小和B文件比较,如果大小一致,说明截图是一样的,也就说明没下载完,反之则说明下载完了。因为,内容不同的图片,大小完全一样,基本上是不可能的。这样,就可以通过比较文件大小来代替比较截图内容是否一致。调试了一下,果然work。

autoIt提供了一些函数,可以实现截屏,比较文件大小等功能:

截屏:
#include <ScreenCapture.au3>

_ScreenCapture_Capture("c:\foo\bar.jpg", $左上角x坐标, $左上角y坐标, $右下角x坐标, $右下角y坐标)

取文件大小:

$fileSize = FileGetSize("c:\foo\bar.jpg")

 

还发现一个问题,因为这个客户端,我是放在虚拟机里用的,结果发现au3Record取出来的坐标都不对。后来发现,需要把客户端窗口拉到屏幕左上角,横竖两边都和屏幕的边缘对齐,这样取出来的坐标才不需要修正,直接可用。

这个方法有个缺陷,就是客户端重新启动后,因为位置改变了,坐标就得重新计算,否则截图会有差异,造成比较失败。后来发现一个方法,用au3Record取好坐标后,再用WinGetPos函数得到客户端窗口的坐标,把这个坐标记下来,在脚本的开头用WinMove函数将客户端窗口移到已计算好坐标的那个位置。这样,每次客户端重新启动后,就不用再重新计算坐标了。

脚本的部分代码如下:

#include <ScreenCapture.au3>
#include <MsgBoxConstants.au3>
Example() Func Example() ;取得下载地址列表 Local $lines = FileReadToArray("c:\temp\turl.txt") Local $lineCount = @extended if $lineCount < 1 Then MsgBox($MB_SYSTEMMODAL, '', "no url") Exit EndIf WinMove("城通网盘客户端","",1,0) ;1,0是用WinGetPos函数得到的坐标 Local $iFileSize = FileGetSize("c:\Downloading.jpg") ;正在下载文件的截图,预先做好 _ScreenCapture_Capture("c:\CurImage.jpg", 810, 187, 836, 234) Local $iCurSize = FileGetSize("c:\CurImage.jpg") while $iFileSize = $iCurSize ;和截屏文件同样大小,说明还在下载 Sleep(60000) ;每隔一分钟检查一次 _ScreenCapture_Capture("c:\CurImage.jpg", 810, 187, 836, 234) ; 2 $iCurSize = FileGetSize("c:\CurImage.jpg") WEnd ;如果没下载完就一直等待 ConsoleWrite(@CRLF) ;记录下载地址以便调试 ConsoleWrite($lines[$lineIdx]) NewDownload($lines[$lineIdx]) ;添加下载任务的函数,具体内容略 $lineIdx = $lineIdx + 1
EndFunc

 

posted @ 2022-04-30 11:22  平静寄居者  阅读(330)  评论(0编辑  收藏  举报