查看: 5769|回复: 7

[原创发布] bitmap=>png 简版

[复制链接]
梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
回帖
705

R考场第七期纪念奖

发表于 2015-8-9 22:35:00 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 SixRC 于 2017-10-16 20:18 编辑

借鉴了 @dant  的范本 获益匪浅 打算自己再写一个 于是就有了这个
相比他的版本 我精简了原有的东西 把取地址和取数据两块重写了 效率高了
不过保存一下小图是根本看不出来的....因为他的已经很快了

2015/9/26 更新一处地方 效率大大提高 汗
2015/9/27 发现不知为何用<<的话效率骤降 是和xp不兼容还是什么 别的版本没试过 所以依旧是xp发布
2015/9/30 发现要改还是有蛮多地方可以改的..这次节省了重复内容
2017/10/10 更新了保存大规格bitmap的脚本
2017/10/16 优化了汇编代码

[pre lang="ruby"]class Bitmap
  #-------------------------------------------------------------------#
  #借鉴dant所成
  #当然 我也努力了 —_—||
  #不 是很努力呢                         -By SixRC
  #-------------------------------------------------------------------#
  #用法为  bitmap.ToPng(filename)
  #假如很追求速度的话 下面的第34行改成
  #data2 = Zlib::Deflate.deflate(@bit_data,1)
  #这样压缩速度会提高(约快一倍) 虽然文件会变大 那个数值可以是1-9 0是不压缩 但不骗你 很慢 因为 写入慢了
  #-------------------------------------------------------------------#
  #--------------------------获取数据头地址---------------
  CWP = Win32API.new('user32.dll','CallWindowProc','ppiii','i')
  GetAddr=[139,116,36,8,139,54,139,118,8,139,118,16,139,124,36,4,137,55,194,16,0].pack("C*")
  def addr
    s="\0"*4
    CWP.call(GetAddr,s,object_id*2+16,0,0)
    s.unpack("L")[0]
  end
  #--------------------------保存为png--------------------
  D1="\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x0\x0\x0\xdIHDR"
  D2="\x8\x6\x0\x0\x0"
  D3="\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82"
  GetData=[85,137,229,139,125,8,49,210,139,101,20,137,227,68,139,69,16,137,198,193,230,3,193,224,2,15,175,224,139,69,12,1,196,139,77,16,66,41,244,88,15,200,193,200,8,137,4,23,141,82,4,73,117,241,75,117,232,137,236,93,194,16,0].pack("C*")
  def ToPng(pl)
    unless @kg
      @addr=addr
      @kg=[width].pack("N")+[height].pack("N")
      c1="IHDR"+@kg+D2
      @crc1=[Zlib.crc32(c1)].pack("N")
      @bit_data="\0"*height*(width*4+1)
    end
    CWP.call(GetData,@bit_data,@addr,width,height)
    data2 = Zlib::Deflate.deflate(@bit_data)
    crc2=[Zlib.crc32("IDAT"+data2)].pack("N")
    sod=[data2.length].pack("N")
    File.open(pl,"w+b"){|i|i.write(D1+@kg+D2+@crc1+sod+"IDAT"+data2+crc2+D3)}
  end
end
[/pre]
假如对象是很大的bitmap
请使用:
code[pre lang="ruby"]#-------------------------------------------------------------------#
#  请运行两次exe
#  第一次是为了生成bitmap对象
#  第二次会读取第一次程序的内存防止内存崩溃
#  11行pl是保存的文件名 例子在下面
#  27行interval是每次保存的高度数 请根据图片大小自行调整 得小于图片高度
#                                    -SixRC   2017.10.10            #
#-------------------------------------------------------------------#
if File.exist?("test.txt")
  #ttt=Time.now
  pl="t.png"
  f=open("test.txt",'r').read.split("/")
  gwtp=Win32API.new('user32','GetWindowThreadProcessId','lp','l')
  op=Win32API.new('kernel32','OpenProcess','lll','l')
  rpm=Win32API.new('kernel32','ReadProcessMemory','llpll','l')
  hwnd=f[0].to_i
  addr=f[1].to_i
  width=f[2].to_i
  height=f[3].to_i
  s="\0"*4
  gwtp.call(hwnd,s)
  hw=op.call(2035711,0,s.unpack('l')[0])
  CWP = Win32API.new('user32.dll','CallWindowProc','pppii','i')
  GetData=[85,137,229,139,125,8,49,210,139,101,20,137,227,68,139,69,16,137,198,193,230,3,193,224,2,15,175,224,139,69,12,1,196,139,77,16,66,41,244,88,15,200,193,200,8,137,4,23,141,82,4,73,117,241,75,117,232,137,236,93,194,16,0].pack("C*")
  gz=Zlib::GzipWriter.open("temp.gz",9)
  xy=[]
  interval=2500
  adler = Zlib.adler32
  for i in 0...height/interval
    xy.unshift([interval*i,interval*(i+1)])
  end
  i+=1
  xy.unshift([interval*i,height]) unless interval*i==height
  for i in xy
    gap=i[1]-i[0]
    temp1="\0"*gap*(width*4)
    temp2="\0"*gap*(width*4+1)
    rpm.call(hw,addr+i[0]*width*4,temp1,width*4*gap,0)
    CWP.call(GetData,temp2,temp1,width,gap)
    adler=Zlib.adler32(temp2,adler)
    gz.write(temp2)
    Graphics.update
  end
  gz.close
  fsize = File.size("temp.gz")
  f = File.open("temp.gz", "rb")
  f.pos = 10
  data2 = "\170\332"
  data2+=f.read(fsize - 18)
  data2+=[adler].pack("N")
  temp1=temp2=nil
  D1="\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x0\x0\x0\xdIHDR"
  D2="\x8\x6\x0\x0\x0"
  D3="\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82"
  @kg=[width].pack("N")+[height].pack("N")
  c1="IHDR"+@kg+D2
  @crc1=[Zlib.crc32(c1)].pack("N")
  crc2=[Zlib.crc32("IDAT"+data2)].pack("N")
  sod=[data2.length].pack("N")
  File.open(pl,"wb"){|i|i.write(D1+@kg+D2+@crc1+sod+"IDAT"+data2+crc2+D3)}
# p Time.now-ttt
  exit
end

class Bitmap
  CWP = Win32API.new('user32.dll','CallWindowProc','ppiii','i')
  GetAddr=[139,116,36,8,139,54,139,118,8,139,118,16,139,124,36,4,137,55,194,16,0].pack("C*")
  def addr
    s="\0"*4
    CWP.call(GetAddr,s,object_id*2+16,0,0)
    s.unpack("L")[0]
  end
end
#测试用图
#b=Bitmap.new(15000,15000)
#c=Bitmap.new("1.png")
#r=Rect.new(0,0,200,200)
#for i in 0..74
#  for j in 0..74
#    b.blt(i*200,j*200,c,r)
#  end
#end
b=Bitmap.new("tt.png")
Hwnd=Win32API.new("user32", "GetActiveWindow", 'v', 'L').call
f=open("test.txt",'w')
f.write(Hwnd.to_s+"/"+b.addr.to_s+"/"+b.width.to_s+"/"+b.height.to_s)
f.close
loop{Graphics.update}[/pre]







点评

@晴兰 不过我不会!我做的任何都绝对不是专业的!我还要慢慢进化!  发表于 2015-9-30 18:45
不用<<你可以用join。另外这种方式是我早期纯黑的产物。现在我们都有组织有纪律的黑了,可以用DSL来写这些机器码。  发表于 2015-9-30 02:40
梦石
0
星屑
9292
在线时间
2504 小时
注册时间
2011-5-20
回帖
14521

开拓者

发表于 2015-8-9 22:45:17 | 显示全部楼层
那么这是一个截图脚本?
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复

使用道具 举报

梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
回帖
705

R考场第七期纪念奖

 楼主| 发表于 2015-8-9 22:47:10 | 显示全部楼层
chd114 发表于 2015-8-9 22:45
那么这是一个截图脚本?

ya 标题不是很直白吗...
回复

使用道具 举报

梦石
0
星屑
9292
在线时间
2504 小时
注册时间
2011-5-20
回帖
14521

开拓者

发表于 2015-8-9 22:50:59 | 显示全部楼层
SixRC 发表于 2015-8-9 05:47
ya 标题不是很直白吗...

我差点以为是别的什么用途的脚本···

点评

其实 gif和png连放真的是一样的 两个都是一帧一幅画 从播放的角度讲 完全没有区别 更连贯一定是错觉  发表于 2015-8-10 00:26
没有啊 先全加载好 完全没差的 不过我不懂具体原理..说错了不要找我  发表于 2015-8-9 23:27
GIF连贯一些···  发表于 2015-8-9 23:24
做动画 我都是先保存为png然后piapiapia的一张张放 效果很好啊 先找软件把png压缩一下就不会大 为什么要gif呢 ...以及我不懂gif的格式..而且去搞懂真是...  发表于 2015-8-9 23:22
来个做GIF的吧···这样的话做预告也能省点事···  发表于 2015-8-9 23:19
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复

使用道具 举报

…あたしは天

梦石
0
星屑
2308
在线时间
4033 小时
注册时间
2010-10-4
回帖
10548

开拓者贵宾

发表于 2015-8-10 10:01:29 | 显示全部楼层
本帖最后由 taroxd 于 2015-8-10 10:13 编辑

全程机器码的感觉如何……

然后,在VA里,不同编码的字符串是不能+的

改成这样就是通用发布了:
  1. File.open(pl,"wb"){|i|i<<D1<<kg<<D2<<crc1<<sod<<'IDAT'<<data<<crc2<<D3}
复制代码

点评

已改  发表于 2015-8-10 13:12
其实是调试完代码就快奔溃了 明明感觉没错 居然总是 内存不能为read..简直死 然后发现写错了 真是..测试完就好开心 别的都不想管了  发表于 2015-8-10 13:01
我也想要16进制!不过翻译的软件 译成16进制 中间没逗号..我又懒得自己写脚本处理 就这样了... 突然想到可以复制到空白文档里把空格替换一下..  发表于 2015-8-10 12:59
其实s20的callproc还算semantic的,也不是\xAA\xBB\xCC\xDD啊……  发表于 2015-8-10 10:31
话说为啥不直接 "\xAA\xBB\xCC\xDD" 呢  发表于 2015-8-10 10:22
回复

使用道具 举报

路人党员

梦石
0
星屑
52
在线时间
2276 小时
注册时间
2010-12-30
回帖
3011
发表于 2015-8-10 11:21:08 | 显示全部楼层
机械码让人感觉不安全啊==

点评

well,相信没事就好了 这个真是没问题的...我也不黑心...纯粹学以致用  发表于 2015-8-10 13:04
本人擅长XP,如果有脚本或者Ruby方面的问题欢迎发电邮到engshun@1ppl.me咨询,本人很少检查电邮所以不一定会及时回复,本人不会直接出手解决问题只会提供一个方向,所以谢绝伸手党
回复

使用道具 举报

梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
回帖
705

R考场第七期纪念奖

 楼主| 发表于 2015-9-27 11:19:13 | 显示全部楼层
单纯是更新示意
这样子算是最终版了
恩 就是这样
回复

使用道具 举报

老黄鸡

梦石
4
星屑
45733
在线时间
7952 小时
注册时间
2009-7-6
回帖
13338

MZ评测员RM创作大赛01组委会开拓者贵宾

发表于 2015-9-28 02:35:32 | 显示全部楼层
我觉得紫苏原来那个纯ruby版的已经很快了。

点评

关于那个版本 很难过地说 我找不到.....  发表于 2015-9-30 19:02
RGDirect - DirectX驱动的RGSS,点我了解.
(排满,暂停)RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部