Created
December 23, 2014 12:58
-
-
Save rutan/c7a3951d6575fc3af1e1 to your computer and use it in GitHub Desktop.
RGSS3 PNG出力案
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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