Skip to content

Instantly share code, notes, and snippets.

@rutan
Created December 23, 2014 12:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rutan/c7a3951d6575fc3af1e1 to your computer and use it in GitHub Desktop.
Save rutan/c7a3951d6575fc3af1e1 to your computer and use it in GitHub Desktop.
RGSS3 PNG出力案
# encoding: utf-8
module Torigoya
module Win32
# メモリのコピー
# @param [Integer, Object] destination コピー先のアドレス、またはバッファ
# @param [Integer, Object] source コピー元のアドレス、またはバッファ
# @param [Integer] size コピーする領域のサイズ
# @return [void]
def self.rtl_move_memory(destination, source, size)
func =
if destination.kind_of?(Integer)
if source.kind_of?(Integer)
@rtl_move_memory_aa ||= Win32API.new('kernel32', 'RtlMoveMemory', 'lll', 'l')
else
@rtl_move_memory_ab ||= Win32API.new('kernel32', 'RtlMoveMemory', 'lpl', 'l')
end
else
if source.kind_of?(Integer)
@rtl_move_memory_ba ||= Win32API.new('kernel32', 'RtlMoveMemory', 'pll', 'l')
else
@rtl_move_memory_bb ||= Win32API.new('kernel32', 'RtlMoveMemory', 'ppl', 'l')
end
end
func.call(destination, source, size)
end
end
end
module Torigoya
# Bitmapのデータをメモリから出力する。
# RGSS WikiのBitmap Marshal対応の内部処理のラッパー。
# 参考元: RGSS Wiki http://tkool.web-ghost.net/wiki/wiki.cgi?page=Script%2FBitmap%A4%CEMarshal%C2%D0%B1%FE
module BitmapExporter
class Base
# 初期化
# @param [Bitmap] 操作対象のBitmap
def initialize(bitmap)
@bitmap = bitmap
end
attr_reader :bitmap
# Bitmapの生データを出力する
# @return [String] Bitmapの生データ
def dump_raw_data
("\0" * (4 * @bitmap.width * @bitmap.height)).tap do |buf|
Win32.rtl_move_memory(buf, bitmap_address, buf.bytesize)
end
end
# Bitmapの画像データが格納されているアドレスを取得
# @return [Integer]
def bitmap_address
buf = "\0" * 4
address = @bitmap.object_id * 2 + 16
Win32.rtl_move_memory(buf, address, 4)
address = buf.unpack("L")[0] + 8
Win32.rtl_move_memory(buf, address, 4)
address = buf.unpack("L")[0] + 16
Win32.rtl_move_memory(buf, address, 4)
buf.unpack("L")[0]
end
end
class PNGExporter < Base
# PNGファイルに出力する
# @param [String] filename 出力ファイル名
def export(filename)
File.open(filename, 'wb') do |f|
f.write "\x89PNG\r\n\x1a\n"
f.write convert_chunk('IHDR', [@bitmap.width, @bitmap.height, 8, 6, 0, 0, 0].pack('N2C5'))
f.write convert_chunk('IDAT', Zlib::Deflate.deflate(generate_image))
f.write convert_chunk('IEND', '')
end
rescue => e
puts e.inspect
puts e.backtrace
end
private
def convert_chunk(name, data)
[data.bytesize, name, data, Zlib.crc32("#{name}#{data}")].pack('NA4A*N')
end
def generate_image
self.dump_raw_data.each_byte.each_slice(4).map { |color|
[color[2], color[1], color[0], color[3]]
}.each_slice(@bitmap.width).to_a.reverse.map { |line|
([0] + line.flatten).pack('C*')
}.join
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment