RPGツクールXP/VX用のRGSS素材です。
一部英語版対応です。
(A few materials can be used for English RPG MAKER XP/VX.)
競合率はルファーの独断と偏見なのでたまにハズレます。
#==============================================================================
# ■ DIB 出力ライブラリ
#------------------------------------------------------------------------------
# ビットマップオブジェクトを DIB (*.bmp) ファイルに出力します。
# 対応RGSS : 1 2
# (C) ルファー
# WebSite https://tkoolerlufar.pages.dev/
#==============================================================================
=begin
=対応RGSS
1 2
=必要なライブラリ
ルファー作スクリプト素材共通ライブラリ
=他の素材との競合の可能性
... 考える必要ナシ
=RPGツクールXPでの導入方法
Main より上に新セクションを作成して、このプログラムをそこにコピーする
=使い方。
Bitmap クラスの「write_to_bmp_file」メソッドを呼び出すことで、
そのビットマップを bmp ファイルに出力します。
文法:
write_to_bmp_file(file[, show_progress])
* file : 出力先ファイルのパスまたは出力先 IO
* show_progress : 進歩状況を表示するかどうか (初期値 true)
show_progress を true にしても、メモリが無いと進行状況を表示しません。
なお、RPGツクールXPでは、この引数に false を与えると
ハングアップすることがあるので気をつけてください。
=出力する DIB について。
ビットマップオブジェクトの幅か高さのいずれかが
2,147,483,647 ピクセルを超えると出力できません。
ま、そんなビットマップ作らないと思うけど。
解像度は、はがきサイズ (横10cm X 縦14.1cm) に合わせます。
透明ピクセルの色は不明です。隠しピクセルとかあるかも?
試しにウィンドウスキンの「001-Blue01」を出力してみてはどうでしょう。
=参考サイト。ありがとうございます!
Wikipedia
http://ja.wikipedia.org/wiki/Windows_bitmap
http://en.wikipedia.org/wiki/Device-independent_bitmap
MSDN オンライン
http://msdn.microsoft.com/en-us/library/dd183374(VS.85).aspx
http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx
=更新履歴
2010/06/01 解像度が、はがきの背景サイズに合わせていたのを前景サイズに修正
2010/04/13 公開
=新規定義しているメソッド
Bitmap#write_to_bmpfile
=end
#----------------------------------------------------------------------------
# ◆ Bitmap クラス
#----------------------------------------------------------------------------
class Bitmap
#--------------------------------------------------------------------------
# ○ DIB ファイルへの書き込み
# file : 出力先ファイルのパスまたは出力先 IO
# show_progress : 進歩状況を表示するかどうか (初期値 true)
#--------------------------------------------------------------------------
def write_to_bmpfile(file, show_progress = true)
if width > 0x7fffffff or height > 0x7fffffff
raise(RuntimeError, "ビットマップが大きすぎます。", caller)
end
begin
# 「お待ちください」
if show_progress
begin
colorless = Color.new(0.0, 0.0, 0.0, 0.0)
sprite = Sprite.new
sprite.z = 077777
sprite.bitmap = Bitmap.new(screen_width, screen_height)
sprite.bitmap.fill_rect(0, 0, screen_width, screen_height,
colorless)
sprite.bitmap.draw_text(0, screen_height / 2 - 32, screen_width, 32,
"WRITING A BITMAP TO A DIB IMAGE. PLEASE WAIT....", 1)
sprite.bitmap.font.color = Color.new(128.0, 128.0, 128.0)
rescue RGSSError
raise if $!.message !~ /^failed to create /
show_progress = false
end
end
refresh_progress = Proc.new {|str|
next unless show_progress
sprite.bitmap.fill_rect(0, screen_height / 2, screen_width, 32,
colorless)
sprite.bitmap.draw_text(0, screen_height / 2, screen_width, 32, str)
}
# 何秒もビジー状態になると不安になってくるので
# 別スレッドで進歩状況を表示しながら処理
processing = true
thread_which_update_frame = Thread.start do
unless show_progress
Thread.stop
Thread.exit
end
frame_count = Graphics.frame_count
frame_rate = Graphics.frame_rate
Graphics.frame_count = 0
Graphics.frame_rate = 10
while processing
sprite.visible = Graphics.frame_count & 0b10 != 0
Graphics.update
sleep(0.5 / Graphics.frame_rate)
end
Graphics.frame_count = frame_count
Graphics.frame_rate = frame_rate
sprite.bitmap.dispose
sprite.dispose
end
# メイン処理
## ファイルサイズ計算
bmp_size = (self.width * 3 + self.width % 4) * self.height
file_size = 14
file_size += 40
file_size += bmp_size
## BITMAPFILEHEADER
refresh_progress.call("file header")
packed_fh = Array.new
packed_fh << "BM" # 識別子
packed_fh << file_size # ファイルサイズ
packed_fh << 0 # 予約A
packed_fh << 0 # 予約B
packed_fh << 14 + 40 # 画像データの開始位置
## BITMAPINFOHEADER
refresh_progress.call("information header")
resolution =
[self.width * 10, Integer(self.height * 5.0 * Math.sqrt(2.0))].max
packed_ih = Array.new
packed_ih << 40 # BITMAPINFOHEADER のサイズ
packed_ih << self.width # 幅
packed_ih << self.height # 高さ
packed_ih << 1 # 面の数
packed_ih << 24 # ビット深度
packed_ih << 0 # 圧縮方式
packed_ih << bmp_size # 画像データのサイズ
packed_ih << resolution # 横解像度 [ピクセル/m]
packed_ih << resolution # 縦解像度
packed_ih << 0 # 使っている色数
packed_ih << 0 # 重要な色数
## 画像データ
refresh_progress.call("image data")
image_data = String.new
self.height.times do |_y|
y = self.height - 1 - _y
refresh_progress.call(sprintf(
"image data (%d%%)", _y * 100 / self.height))
self.width.times do |x|
px = self.get_pixel(x, y)
image_data << px.blue.to_i
image_data << px.green.to_i
image_data << px.red.to_i
end
(self.width % 4).times {|i| image_data << 0 }
end
## 書く
refresh_progress.call("")
out = file.instance_of?(String) ? File.open(file, "wb") : file
out.print(
packed_fh.pack("a2VvvV") + packed_ih.pack("VVVvvVVVVVV") + image_data)
out.close if file.instance_of?(String)
processing = false
thread_which_update_frame.run.join
return false
rescue SystemCallError
$@ = caller
processing = false
thread_which_update_frame.run.join
raise
end
end
end
戻る