设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2080|回复: 0
打印 上一主题 下一主题

[原创发布] win32 RGSSBitmap的“属性应用”

[复制链接]

Lv4.逐梦者

梦石
0
星屑
6483
在线时间
119 小时
注册时间
2020-1-8
帖子
234
跳转到指定楼层
1
发表于 2022-2-3 23:48:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
参考资料:RPG Maker的Bitmap类的结构
                 还有一个英文网站,我找不到了……

RUBY 代码复制
  1. module CWP
  2.   CallWndProc = Win32API.new('user32', 'CallWindowProc', 'PLLLL', 'L')
  3.   CodeMove = [139,68,36,4,133,192,116,23,209,224,185,2,0,0,0,139,20,140,133,
  4.     210,116,9,139,4,16,65,131,249,5,117,240,194,16,0].pack('C*')
  5.  
  6.   def self.move(obj, offsetA=16, offsetB=0, offsetC=0)
  7.     CallWndProc.call(CodeMove, obj, offsetA, offsetB, offsetC)
  8.   end
  9. end
  10.  
  11. class Bitmap
  12.   def to_int
  13.     self.object_id
  14.   end
  15.  
  16.   def hBitmap
  17.     @_hBitmap ||= CWP.move(self, 16, 8, 44)
  18.   end
  19.  
  20.   def pBits
  21.     @_pBits ||= CWP.move(self, 16, 8, 16)
  22.   end
  23.  
  24.   def pScan0
  25.     @_pScan0 ||= CWP.move(self, 16, 8, 12)
  26.   end
  27.  
  28.   def pIHr
  29.     @_pIHr ||= CWP.move(self, 16, 8, 8) # 或者 CWP.move(self, 16, 8, 32)
  30.   end
  31. end
  32.  
  33. module WIN32API
  34.   @@default_w = 640
  35.   @@default_h = 480
  36.  
  37.   threadID = Win32API.new('kernel32', 'GetCurrentThreadId', 'V', 'L').call()
  38.   hwnd = Win32API.new('user32', 'GetForegroundWindow', 'V', 'L').call()
  39.   _GetWndTidPid = Win32API.new('user32','GetWindowThreadProcessId', 'LP', 'L')
  40.   _FindWindowEx = Win32API.new('user32', 'FindWindowEx', 'LLPP', 'L')
  41.   while _GetWndTidPid.call(hwnd, nil) != threadID
  42.     hwnd = _FindWindowEx.call(0, hwnd, "RGSS Player", nil)
  43.   end
  44.   Hwnd = hwnd
  45.  
  46.   GetDC = Win32API.new('user32', 'GetDC', 'L', 'L')
  47.   ReleaseDC = Win32API.new('user32', 'ReleaseDC', 'LL', 'L')
  48.   CreateCompatibleDC = Win32API.new('gdi32', 'CreateCompatibleDC', 'L', 'L')
  49.   DeleteDC = Win32API.new('gdi32', 'DeleteDC', 'L', 'I')
  50.   DeleteObject = Win32API.new('gdi32', 'DeleteObject', 'L', 'I')
  51.   SelectObject = Win32API.new('gdi32', 'SelectObject', 'LL', 'L')
  52.   BitBlt = Win32API.new('gdi32', 'BitBlt', 'LIIIILIIL', 'I')
  53.   StretchBlt = Win32API.new('gdi32', 'StretchBlt', 'LIIIILIIIIL', 'I')  
  54.   SetStretchBltMode = Win32API.new('gdi32', 'SetStretchBltMode', 'LI', 'I')
  55.   SetBrushOrgEx = Win32API.new('gdi32', 'SetBrushOrgEx', 'LIIP', 'I')
  56.  
  57.   SRCCOPY = 0xCC0020
  58.   SRCPAINT = 0xEE0086
  59.   STRETCH_HALFTONE = 4
  60.  
  61.   def self.snap_to_bitmap(src_x = 0, src_y = 0, src_w = @@default_w,
  62.       src_h = @@default_h, dest_w = @@default_w, dest_h = @@default_h)
  63.  
  64.     bitmap = Bitmap.new(dest_w, dest_h)
  65.     hDC = GetDC.call(Hwnd)
  66.     mCDC = CreateCompatibleDC.call(hDC)
  67.     oldBitmap = SelectObject.call(mCDC, bitmap.hBitmap)
  68.  
  69.     if src_w == dest_w && src_h == dest_h
  70.       BitBlt.call(mCDC, 0, 0, dest_w, dest_h, hDC, 0, 0, SRCCOPY)
  71.     else
  72.       SetStretchBltMode.call(mCDC, STRETCH_HALFTONE)
  73.       SetBrushOrgEx.call(mCDC, 0, 0, nil)
  74.       StretchBlt.call(mCDC, 0, 0, dest_w, dest_h, hDC, src_x, src_y, src_w,
  75.         src_h, SRCPAINT)
  76.     end
  77.  
  78.     SelectObject.call(mCDC, oldBitmap)
  79.     DeleteDC.call(mCDC)
  80.     ReleaseDC.call(Hwnd, hDC)
  81.  
  82.     bitmap
  83.   end
  84.  
  85.   MultiByteToWideChar =
  86.     Win32API.new('kernel32', 'MultiByteToWideChar', 'ILPIPI', 'I')   
  87.   CP_UTF8 = 65001
  88.  
  89.   def self.utf16(text)
  90.     len = MultiByteToWideChar.call(CP_UTF8, 0, text, -1, nil, 0)
  91.     buf = "\0" * (len * 2)
  92.     MultiByteToWideChar.call(CP_UTF8, 0, text, -1, buf, len)
  93.     buf
  94.   end
  95.  
  96.   GdiplusStartup = Win32API.new('gdiplus', 'GdiplusStartup', 'PPP', 'I')
  97.   GdiplusShutdown = Win32API.new('gdiplus', 'GdiplusShutdown', 'L', 'V')
  98.   GdipStartupInput = [1, 0, 0, 0].pack('L4')
  99.  
  100.   GdipCreateBitmapFromGdiDib =
  101.     Win32API.new('gdiplus', 'GdipCreateBitmapFromGdiDib', 'LLP', 'I')
  102.   GdipDisposeImage = Win32API.new('gdiplus', 'GdipDisposeImage', 'L', 'I')
  103.   GdipSaveImageToFile =
  104.     Win32API.new('gdiplus', 'GdipSaveImageToFile', 'LPPP', 'I')
  105.  
  106.   fixed = [6660, 4563, 154, 115, 0, 0, 248, 30, 243, 46].pack('SSC8')
  107.   ClsidEncoder = {
  108.     :bmp => [1434252288].pack('L') << fixed,
  109.     :jpg => [1434252289].pack('L') << fixed,
  110.     :png => [1434252294].pack('L') << fixed
  111.     }
  112.  
  113.   def self.save_bitmap_to_pic(rgss_bitmap, filename, type=:png)
  114.     buf = "\0" * 4
  115.     GdiplusStartup.call(buf, GdipStartupInput, nil)
  116.     token = buf.unpack('L')[0]
  117.  
  118.     GdipCreateBitmapFromGdiDib.call(rgss_bitmap.pIHr, rgss_bitmap.pBits, buf)      
  119.     pBitmap = buf.unpack('L')[0]   
  120.     GdipSaveImageToFile.call(pBitmap, self.utf16(filename),
  121.       ClsidEncoder[type] || ClsidEncoder[:png], nil)
  122.  
  123.     GdipDisposeImage.call(pBitmap)
  124.     GdiplusShutdown.call(token)
  125.   end
  126. end


以前只会用论坛上的Bitmap#address方法,并不知道其含义,具体可以看看链接中的解释(代码需鼠标手动拉开……)。

全部为Win32API的调用,主要为基本过程,并没有对方法的参数及API返回值做判断,
具体参数类型及取值参照变量名,有需求请自行修改。

WIN32API.snap_to_bitmap         
  由gdi实现,截屏为位图的功能,可局部缩放。
  用到 Bitmap#hBitmap(完全可以把RGSSBitmap当作GDI的Bitmap对象使用)
  示例:以屏幕左上角 Rect(0, 0, 320, 240) 区域图像生成 640×480 大小的位图对象
            bitmap = WIN32API.snap_to_bitmap(0, 0, 320, 240, 640, 480)
            #bitmap.dispose

WIN32API.save_bitmap_to_pic   
  由gdi+实现,保存位图为图片(png,jpg,bmp)。
  用到 Bitmap#pIHr(GDI中的BITMAPINFOHEADER); Bitmap#pBits(RGSSBitmap中图像数据内存的起始地址)
  示例:以bitmap对象保存为名为 “截屏.jpeg” 的图片文件
            # bitmap
            WIN32API.save_bitmap_to_pic(bitmap, "截屏.jpeg", :jpg)
            # bitmap.dispose
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-25 09:07

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表