0x01 前言
尝试用c#写一个截图OCR识别软件,原本以为很简单的项目,结果实现起来发现并不简单,期间遇到很坑,写篇文章记录下。
0x02 系统缩放与布局
为了看得清楚,尤其是对于屏幕分辨率为1920*1080的笔记本,系统都推荐将缩放比例设置为125%,也就是等比例放大显示。然而Windows库默认返回的都是100%缩放,也就导致截图时无法获取到屏幕的真实分辨率。
如图我的笔记本设置的是125%缩放比例,下图代码的功能是截取全屏并保存到剪贴板:
实际截取到的大小:
当乘上屏幕缩放比例后:
于是开始找资料,发现可以通过获取系统DPI,然后通过DPI获取屏幕缩放比例:
那么下一步要做的就是如何获取DPI,在StackOverFlow上发现有人给出了解答,Graphics
类提供了DpiX、DpiY方法,可以直接获取:
自己试了之后发现Graphics
类并不靠谱,永远返回的都是96。无奈,只得另寻他法:通过Win32-ManagementClass
程序启动的时候获取缩放比例就好了:
0x03 键盘hook
查了很多资料,很多全局hook都不太满意,退而求其次,用GetAsyncKeyState()这个API
0x04 鼠标坐标获取
(还是必须要乘以屏幕缩放比例才能获取到真实的坐标)
0x05 总结
程序启动的时候先通过DPI获取屏幕缩放比例,使用Timer
控件+GetAsyncKeyState()
函数的方法实现伪全局hook,监听到一次组合键就调用CapScreenShot()
方法获取鼠标坐标
最后将两个点的X和Y坐标相减取绝对值就得到了画布大小,最后调用Graphics
的CopyFromScreen()
方法实现区域截图: