Project1

标题: 通过 Graphics.freeze 获得截图 [打印本页]

作者: SixRC    时间: 2017-11-5 14:46
标题: 通过 Graphics.freeze 获得截图
本帖最后由 SixRC 于 2018-1-27 20:12 编辑

18.1.27
之前是直接不管三七二十一把位图结构拷贝过去了 所以不能dispose 而F12的时候释放了位图会出错
现在新建的位图大小和分辨率一致 只把结构中关于数据操作的一部分拷过去了 F12时释放的还是原来新建的位图
范例还是老的范例 其实只要截图不需要在freeze的时候改位图的话不需要那么麻烦 拿到freeze的位图数据地址就行了
只要截图的话还可以不需要借助freeze只需要画面刷新
不过 颓废中 暂置

17.12.3
发现还需要修改一处数据 否则freeze的大小仍为640×480
暂留置不做处理


此处代码

这里原理及介绍
rgss 初始创建了一张窗口大小的位图用于之后的 freeze 操作
那张位图数据结构地址见脚本
这脚本就是新建了个$snapshot 然后把结构整个从freeze位图拷到$snapshot了
每一次 freeze 这张图都是 freeze 时显示的画面
操作 $snapshot 相当于操作 freeze 时的画面
你也可以 不需要精灵 改 $snapshot 就等于改了 freeze 时候的画面
要截图 只要freeze transition(0) 然后保存 $snapshot 就可以了

因为原生态 截图是不会有什么副作用的 比方遮挡啊全屏啊等等 游戏显示正常 截图必然显示正常
不过分辨率若不是在 dll 初始就改 freeze 只能 freeze 到初始的分辨率
下面截图范例
freeze截图范例.zip (203.97 KB, 下载次数: 116)




作者: fux2    时间: 2017-11-6 14:13
LoadLibrary这用法怕是有点谜2333,虽然结果一样,一般还是getmodulehandle吧。
这玩意我在自己的工程里倒是已经实现了,不过我并不是改写Graphics.freeze,感觉有点绕。
你如果仔细跟进会发现Graphics.freeze的第三个(好像是第三个)call才是真实描绘的地方,我这里的地址是dll+0x15470
你把ecx赋值成Graphics指针,再把hdc传入就可以了,剩下的交给这个函数……

当然实际上是异曲同工,你这种方法的优点是不用处理不同色位的情况,我这个不需要改写Graphics.freeze,理论兼容性好一丢丢。
作者: SixRC    时间: 2017-11-6 22:57
本帖最后由 SixRC 于 2017-11-6 23:28 编辑
fux2 发表于 2017-11-6 14:13
LoadLibrary这用法怕是有点谜2333,虽然结果一样,一般还是getmodulehandle吧。
这玩意我在自己的工程里倒 ...

明明是hmodule+0x15470吧...
你的重点肯定在黑显示的画面
我还没开始那样想..
我一直很疑惑为什么要有640*8的位图
刚刚知道DC怎么用的才明白为什么没有一张专门用于显示的位图
都是用完就扔掉了..
然后我开始回跟freeze位图的内存地址
最终找到它的数据结构在
[[hmodule+0x12B6C4]+0x144]
[[[hmodule+0x12B6C4]+0x134]+0xB4]是那张640*8..
这样就不用改任何东西了。。
这结构和Bitmap存的一模一样
我开始猜它是初始时候定义的Bitmap
不过不是 但作用估计一样
期间有了一些猜测和好玩的发现
就是精灵类的 z 值等于最大的时候会顶掉freeze图显示在屏幕上....

不过还有一件事想不通的 就是dll开始的时候还创建了一张大小和窗口一样的位图
但是整个过程中就没用到过 想不通


作者: fux2    时间: 2017-11-6 23:25
SixRC 发表于 2017-11-6 22:57
明明是hmodule+0x15470吧...
你的重点肯定在黑显示的画面
我还没开始那样想..

我之前写过一个在transition过程中执行代码,就发现z值最大的时候可以覆盖freeze的画面233.
用不上的那张位图我倒是没注意过,改天看看。
作者: fux2    时间: 2018-1-27 17:34
昨天把SixRC君的脚本推荐给朋友之后,发现一个很奇妙的问题,F12之后必然崩溃。
不过我并没有调试,猜测是F12之后copy的内容被清除了,导致freeze时跳转到了不可预知的内容,
不如SixRC君尝试修复一下?
作者: chd114    时间: 2018-1-29 01:48
如果在没有设置全景图的留了空的地图里用截图,截出来的图拖到ps里就是在游戏中显示出来的黑块
没有设置的图块可以在截图时弄成透明吗?这样的话就可以先截一张图然后在ps里慢慢调全景,满意了以后再把全景图保存了放工程,就不用“备份后修改全景图→保存→f12启动”反复测了
作者: SixRC    时间: 2018-1-29 02:33
本帖最后由 SixRC 于 2018-1-29 02:56 编辑

我想原因是rm渲染的时候处理过了alpha值 所以实际显示的时候alpha值不再必要了 截图原理是获取实际显示的位图的内存数据 alpha大概实际渲染后全是255 完全透明的块没有权重变成黑色了
但是sprite们变成最终画面的具体过程未知且干预难度高
所以从原理上貌似无法解决
替代方案
把纯黑色替换成透明?

作者: 黑白无双    时间: 2018-2-21 20:35
不错,感谢楼主分享。




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1