Advertisement
Guest User

Untitled

a guest
Jun 17th, 2018
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 6.02 KB | None | 0 0
  1. # Bitmap Export v5.4 for XP, VX and VXace by Zeus81
  2. # Free for commercial use
  3. # Licence : http://creativecommons.org/licenses/by/4.0/
  4. # Contact : zeusex81@gmail.com
  5. # How to Use :
  6. #   - exporting bitmap :
  7. #       bitmap.export(filename)
  8. #    or bitmap.save(filename)
  9. #
  10. #   - serialize bitmap :
  11. #       open(filename, 'wb') {|file| Marshal.dump(bitmap, file)}
  12. #       bitmap = open(filename, 'rb') {|file| Marshal.load(file)}
  13. #   or
  14. #       save_data(bitmap, filename)
  15. #       bitmap = load_data(filename)
  16. #
  17. #  - snapshot :
  18. #      Graphics.export(filename)
  19. #   or Graphics.save(filename)
  20. #   or Graphics.snapshot(filename)
  21. #   Here filename is optional, and will be replaced by datetime if omitted.
  22.  
  23. $imported ||= {}
  24. $imported[:Zeus_Bitmap_Export] = __FILE__
  25.  
  26. def xp?() false end; alias vx? xp?; alias vxace? xp?
  27. RUBY_VERSION == '1.8.1' ? defined?(Hangup) ?
  28. def xp?() true  end : def vx?() true  end : def vxace?() true  end
  29.  
  30. class String
  31.   alias getbyte  []
  32.   alias setbyte  []=
  33.   alias bytesize size
  34. end unless vxace?
  35.  
  36. class Font
  37.   def marshal_dump()     end
  38.   def marshal_load(dump) end
  39. end
  40.  
  41. class Bitmap
  42.   RtlMoveMemory = Win32API.new('kernel32', 'RtlMoveMemory', 'ppi', 'i')
  43.   def last_row_address
  44.     return 0 if disposed?
  45.     RtlMoveMemory.call(buf=[0].pack('L'), __id__*2+16, 4)
  46.     RtlMoveMemory.call(buf, buf.unpack('L')[0]+8 , 4)
  47.     RtlMoveMemory.call(buf, buf.unpack('L')[0]+16, 4)
  48.     buf.unpack('L')[0]
  49.   end
  50.   def bytesize
  51.     width * height * 4
  52.   end
  53.   def get_data
  54.     data = [].pack('x') * bytesize
  55.     RtlMoveMemory.call(data, last_row_address, data.bytesize)
  56.     data
  57.   end
  58.   def set_data(data)
  59.     RtlMoveMemory.call(last_row_address, data, data.bytesize)
  60.   end
  61.   def get_data_ptr
  62.     data = String.new
  63.     RtlMoveMemory.call(data.__id__*2, [vxace? ? 0x6005 : 0x2007].pack('L'), 4)
  64.     RtlMoveMemory.call(data.__id__*2+8, [bytesize,last_row_address].pack('L2'), 8)
  65.     def data.free() RtlMoveMemory.call(__id__*2, String.new, 16) end
  66.     return data unless block_given?
  67.     yield data ensure data.free
  68.   end
  69.   def _dump(level)
  70.     get_data_ptr do |data|
  71.       dump = Marshal.dump([width, height, Zlib::Deflate.deflate(data, 9)])
  72.       dump.force_encoding('UTF-8') if vxace?
  73.       dump
  74.     end
  75.   end
  76.   def self._load(dump)
  77.     width, height, data = *Marshal.load(dump)
  78.     data.replace(Zlib::Inflate.inflate(data))
  79.     bitmap = new(width, height)
  80.     bitmap.set_data(data)
  81.     bitmap
  82.   end
  83.   def export(filename)
  84.     case format=File.extname(filename)
  85.     when '.bmp'; export_bmp(filename)
  86.     when '.png'; export_png(filename)
  87.     when ''    ; export_png("#{filename}.png")
  88.     else         print("Export format '#{format}' not supported.")
  89.     end
  90.   end
  91.   alias save export
  92.   def export_bmp(filename)
  93.     get_data_ptr do |data|
  94.       File.open(filename, 'wb') do |file|
  95.         file.write(['BM',data.bytesize+54,0,54,40,width,height,
  96.                     1,32,0,data.bytesize,0,0,0,0].pack('a2L6S2L6'))
  97.         file.write(data)
  98.       end
  99.     end
  100.   end
  101.   def export_png(filename)
  102.     data, i = get_data, 0
  103.     if vxace?
  104.       (0).step(data.bytesize-4, 4) do |i|
  105.         byte2 = data.getbyte(i)
  106.         data.setbyte(i, data.getbyte(i+2))
  107.         data.setbyte(i+2, byte2)
  108.       end
  109.     else
  110.       (0).step(data.bytesize-4, 4) do |i|
  111.         data[i,3] = data[i,3].reverse!
  112.       end
  113.     end
  114.     deflate = Zlib::Deflate.new(9)
  115.       null_char, w4 = [].pack('x'), width*4
  116.       (data.bytesize-w4).step(0, -w4) {|i| deflate << null_char << data[i,w4]}
  117.       data.replace(deflate.finish)
  118.     deflate.close
  119.     File.open(filename, 'wb') do |file|
  120.       def file.write_chunk(chunk)
  121.         write([chunk.bytesize-4].pack('N'))
  122.         write(chunk)
  123.         write([Zlib.crc32(chunk)].pack('N'))
  124.       end
  125.       file.write("\211PNG\r\n\32\n")
  126.       file.write_chunk(['IHDR',width,height,8,6,0,0,0].pack('a4N2C5'))
  127.       file.write_chunk(data.insert(0, 'IDAT'))
  128.       file.write_chunk('IEND')
  129.     end
  130.   end
  131. end
  132.  
  133. module Graphics
  134.   if xp?
  135.     FindWindow             = Win32API.new('user32', 'FindWindow'            , 'pp'       , 'i')
  136.     GetDC                  = Win32API.new('user32', 'GetDC'                 , 'i'        , 'i')
  137.     ReleaseDC              = Win32API.new('user32', 'ReleaseDC'             , 'ii'       , 'i')
  138.     BitBlt                 = Win32API.new('gdi32' , 'BitBlt'                , 'iiiiiiiii', 'i')
  139.     CreateCompatibleBitmap = Win32API.new('gdi32' , 'CreateCompatibleBitmap', 'iii'      , 'i')
  140.     CreateCompatibleDC     = Win32API.new('gdi32' , 'CreateCompatibleDC'    , 'i'        , 'i')
  141.     DeleteDC               = Win32API.new('gdi32' , 'DeleteDC'              , 'i'        , 'i')
  142.     DeleteObject           = Win32API.new('gdi32' , 'DeleteObject'          , 'i'        , 'i')
  143.     GetDIBits              = Win32API.new('gdi32' , 'GetDIBits'             , 'iiiiipi'  , 'i')
  144.     SelectObject           = Win32API.new('gdi32' , 'SelectObject'          , 'ii'       , 'i')
  145.     def self.snap_to_bitmap
  146.       bitmap  = Bitmap.new(width, height)
  147.       info    = [40,width,height,1,32,0,0,0,0,0,0].pack('LllSSLLllLL')
  148.       hDC     = GetDC.call(hwnd)
  149.       bmp_hDC = CreateCompatibleDC.call(hDC)
  150.       bmp_hBM = CreateCompatibleBitmap.call(hDC, width, height)
  151.       bmp_obj = SelectObject.call(bmp_hDC, bmp_hBM)
  152.       BitBlt.call(bmp_hDC, 0, 0, width, height, hDC, 0, 0, 0xCC0020)
  153.       GetDIBits.call(bmp_hDC, bmp_hBM, 0, height, bitmap.last_row_address, info, 0)
  154.       SelectObject.call(bmp_hDC, bmp_obj)
  155.       DeleteObject.call(bmp_hBM)
  156.       DeleteDC.call(bmp_hDC)
  157.       ReleaseDC.call(hwnd, hDC)
  158.       bitmap
  159.     end
  160.   end
  161.   class << self
  162.     def hwnd() @hwnd ||= FindWindow.call('RGSS Player', nil) end
  163.     def width()  640 end unless method_defined?(:width)
  164.     def height() 480 end unless method_defined?(:height)
  165.     def export(filename=Time.now.strftime("snapshot %Y-%m-%d %Hh%Mm%Ss #{frame_count}"))
  166.       bitmap = snap_to_bitmap
  167.       bitmap.export(filename)
  168.       bitmap.dispose
  169.     end
  170.     alias save     export
  171.     alias snapshot export
  172.   end
  173. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement