Windows 截图原理,高难度问题,请慎入

2020-12-31 09:53:44 +08:00
 cool1205
windows 截图可以使用 windows 自带的,也可以使用 QQ 等辅助工具截图,效果还是可以的。我想请教各位大神一个问题,windows 通过 API 截图是拿的哪里的数据,这可能与 windows 刷新屏幕有关系了,windows 是直接从屏幕直接截取,还是从内存中直接获取。这么说有些抽象,比如屏幕刷新率是 1HZ (例子而已),那就是一秒屏幕更新一下,此时有个程序每隔 0.1 秒向控制台输出当前毫秒时间戳,那此时使用截图工具,截到图片的时间戳会不会一秒内截图的十张图片一样,还是十张不一样。我尝试使用软件去验证,但不存在可操作性,希望有大哥指教一二
10457 次点击
所在节点    程序员
53 条回复
murmur
2020-12-31 09:56:53 +08:00
虽然原理不知道么,但是你没用过截图工具么,你按下快捷键的一刻,已经先生成屏幕的截图了,此时屏幕是被截图盖住的,你可以继续框选

另外 qq 的截图应该不是一般的 api,现在的截图工具都得支持 dx,太老的 api 截不到 dx 的游戏
zocome
2020-12-31 09:58:15 +08:00
同关注,我也一直有这个疑问
IGJacklove
2020-12-31 10:05:43 +08:00
十张一样的吧,你都没刷新,只有在一秒之后才能拿到不一样的值吧。
Tumblr
2020-12-31 10:07:19 +08:00
@levie 来个高难度的回答。。。
opengps
2020-12-31 10:11:15 +08:00
虽然高难度不敢发言,不过软件验证方案很简单,那就是扩展屏下跑毫秒表,这个做法被人用云
murmur
2020-12-31 10:11:32 +08:00
@IGJacklove 但是 ufo 测试屏幕刷新率是说不能用截图验证刷新率,必须用高速相机,楼主这个 1fps 还真难试,60fps 、144 这些倒是能试出来
enenaaa
2020-12-31 10:11:36 +08:00
取得桌面窗口的 DC 句柄,BitBlt 拷贝位图出来就是了。
跟屏幕刷新没关系。
opengps
2020-12-31 10:13:22 +08:00
@opengps 没这玩,回复按钮飘了一下。这个做法被人用来做屏幕延迟测试,在两块屏幕同时显示一样内容下拍照,可以抓到两块屏幕上不同的时间,从而得出延迟差异的毫秒级别时间差
anuding
2020-12-31 10:18:31 +08:00
你把显示器拔了试试看能不能截图不就知道了。
答案应该是不一样,录屏之类的和你显示适配器能产生的图像速度有关吧(大概。
wangkuanglin
2020-12-31 10:24:31 +08:00
没了解过 DX 或者显卡驱动吗?截图就是从显存拿数据,各种工具只是层层封装后的 API 而已,和显示器没关系
h82258652
2020-12-31 10:25:05 +08:00
前几个版本的 win10 有新 API,可以抓窗口或者屏幕
https://docs.microsoft.com/en-us/uwp/api/windows.graphics.capture?view=winrt-19041
老一点版本的 windows,抓窗口完美的做法只能 hook DX,这个我也没弄过,.net 做不了,只能上 C++的。简单的做法就是向目标窗口发送 WM_PAINT,但像 QQ 这种自绘一般抓出来的就是黑色的。
抓屏是从显存取的。后面那个情况应该是 10 张不一样的,具体我也没验证过。
stoneabc
2020-12-31 10:34:56 +08:00
从显存 buffer 取,acuqireNextFrame 我记得是这个 API,阻塞调用直到数据有更新。
ksc010
2020-12-31 10:42:20 +08:00
跟屏幕刷新帧率没关系应该
不过我想楼主的意思应该是显卡的输出帧率吧?
截图操作应该是直接从显存读取的
PopRain
2020-12-31 10:50:48 +08:00
1.屏幕显示是冲显示缓冲去读取数据刷新
2.刷新很快的程序,譬如游戏,用的是双缓冲方式,每次是写一个缓冲区,然后整个切换整个缓冲区,不会存在写一半的问题。
3.缓冲区切换应该有锁机制,不会出现读一半然后缓冲区切换的问题。
4.没有缓冲区切换的普通程序,你抓屏那一刻,位图更新到哪里就截取到哪里,没有影响
NeezerGu
2020-12-31 10:52:36 +08:00
“比如屏幕刷新率是 1HZ (例子而已),那就是一秒屏幕更新一下,此时有个程序每隔 0.1 秒向控制台输出当前毫秒时间戳”

我觉得 lz 可以做个测试,把显示器关了, 然后盲操作截图?
w1573007
2020-12-31 10:54:29 +08:00
我想的是,你看到的显示器是具有刷新的,但数据在显卡中不是刷新的,只是通过显卡输出而已。截图可以理解从显存中读取当前状态,区域截图则是读取一部分的显存
cool1205
2020-12-31 10:55:15 +08:00
我最开始的打算是直接买一个 240hz 的显示器+RTX3070+AMD R7 5800X,这样不管是从哪里截的图片,对于我软件的影响我都能接受。我对硬件与 Windows 系统不是很熟悉。我这样问会更好些,我现在每隔 5ms 需要截取一次屏幕截图,软件控制台输出是 1ms 更新一次,实时抓取,要满足这个条件,60hz 显示器是否足够用?
aloxaf
2020-12-31 11:00:12 +08:00
我总觉得你在提一个 X-Y 问题……
你的目的是抓取某个程序每隔 1ms 输出在控制台上的时间戳?
murmur
2020-12-31 11:03:40 +08:00
@cool1205 240hz 的截图就不要想了,这个实时性可能跟不上,你大概需要一个高速的采集卡
anuding
2020-12-31 11:06:46 +08:00
这个问题和显示器没关系,和你的显卡有关系,首先你的显卡要能够每秒输出 1000 帧以上,即 1000fps 以上。其次,你的控制台应用,这个软件,这个窗口程序,要能支持 1000fps 的刷新率,这一点,要么你自己开个窗口写,要么你就去查 windows 默认的 cmd 支持不支持 1000 帧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/740500

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX