Project1

标题: [XP/VX]将不足画面大小的远景图扩展至画面大小 [打印本页]

作者: 各种压力的猫君    时间: 2011-12-15 14:07
标题: [XP/VX]将不足画面大小的远景图扩展至画面大小
本帖最后由 各种压力的猫君 于 2011-12-15 14:33 编辑

根据VX讨论区问题制作:http://rpg.blue/thread-214013-2-1.html

使用了轮回者的输出Bitmap到Png脚本,在此表示感谢。

[Ntec]Bitmap2Png v1.0 第一部分(输出Btimap到Png)
  1. #==============================================================================
  2. # ■ [Ntec]Bitmap2Png v1.0
  3. #------------------------------------------------------------------------------
  4. #   将Bitmap输出为Png图片。
  5. #-------------------------------------------------------------------------------
  6. #    更新作者: 各种压力的猫君
  7. #    原始作者: 轮回者(协力:柳之一)
  8. #    使用协议: Ntec 支援层脚本
  9. #    RGSS版本: RGSS/RGSS2 (Rpg Maker XP/VX)
  10. #-------------------------------------------------------------------------------
  11. #    更新记录:
  12. #    ◇2011-12-15 v 1.0 by 各种压力的猫君
  13. #    └在原始版本基础上加以修改以适应NEKO_tec脚本内部调用;
  14. #    ◆2008-06-14 v 0.0 by 轮回者 (feat 柳之一)
  15. #    └原始版本;
  16. #-------------------------------------------------------------------------------
  17. #    插入位置:
  18. #      尽可能靠近脚本编辑器脚本列表顶端。
  19. #    使用说明:
  20. #      NEKO_tec 支援层脚本,内部调用。
  21. #===============================================================================

  22. #-------------------------------------------------------------------------------
  23. # ▼ Ntec 通用配置模块
  24. #-------------------------------------------------------------------------------
  25. module Ntec
  26.   module Bitmap2Png
  27.     # 版本号
  28.     VERSION = 1.0
  29.   end
  30. end

  31. #==============================================================================
  32. # PNG文件输出
  33. #   用法:bitmap.save2png(filename)
  34. # BY:轮回者
  35. #==============================================================================

  36. class Bitmap  
  37.   
  38.   # 是否自动颠倒上下?
  39.   #   false时输出图像上下会颠倒,但并不能节省很多时间
  40.   SWITCH_UP2DOWN = true
  41.   
  42.   # 存入PNG文件
  43.   def save2png(filename)
  44.     file = File.open(filename,"wb")
  45.     file.write(make_png_header)
  46.     file.write(make_png_ihdr)
  47.     file.write(make_png_idat)
  48.     file.write(make_png_iend)
  49.     file.close
  50.   end
  51.   
  52.   # PNG文件头数据块
  53.   def make_png_header
  54.     return [0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a].pack("C*")
  55.   end

  56.   # PNG文件情报头数据块(IHDR)
  57.   def make_png_ihdr
  58.     ih_size = [13].pack("N")
  59.     ih_sign = "IHDR"
  60.     ih_width = [width].pack("N")
  61.     ih_height = [height].pack("N")
  62.     ih_bit_depth = [8].pack("C")
  63.     ih_color_type = [6].pack("C")
  64.     ih_compression_method = [0].pack("C")
  65.     ih_filter_method = [0].pack("C")
  66.     ih_interlace_method = [0].pack("C")
  67.     string = ih_sign + ih_width + ih_height + ih_bit_depth + ih_color_type +
  68.             ih_compression_method + ih_filter_method + ih_interlace_method
  69.     ih_crc = [Zlib.crc32(string)].pack("N")
  70.     return ih_size + string + ih_crc
  71.   end
  72.   
  73.   # PNG图像数据(IDAT)
  74.   def make_png_idat
  75.     header = "\x49\x44\x41\x54"
  76.     data = SWITCH_UP2DOWN ? make_png_data : make_png_data2
  77.     data = Zlib::Deflate.deflate(data, 8)
  78.     crc = [Zlib.crc32(header + data)].pack("N")
  79.     size = [data.length].pack("N")
  80.     return size + header + data + crc
  81.   end
  82.   
  83.   # PNG图像数据(点阵);自动颠倒上下
  84.   def make_png_data
  85.     data = get_data.unpack('x2aX2aX2ax2a'*height*width).to_s
  86.     len = width * 4      
  87.     for y in 0...height
  88.       break if 2*y >= height - 1
  89.       nth1 = y * len      
  90.       nth2 = (height - 1 - y) * len      
  91.       tStr = data[nth1,len]      
  92.       data[nth1, len] = data[nth2, len]      
  93.       data[nth2, len] = tStr
  94.     end
  95.    
  96.     for y in 0...height
  97.       nth = (height - 1 - y) * width * 4
  98.       data.insert(nth,"\000")
  99.     end
  100.     return data
  101.   end
  102.   
  103.   # PNG图像数据(点阵);不自动颠倒上下
  104.   def make_png_data2
  105.     data = get_data.unpack('x2aX2aX2ax2a'*height*width).to_s
  106.     for y in 0...height
  107.       nth = (height - 1 - y) * width * 4
  108.       data.insert(nth,"\000")
  109.     end
  110.     return data
  111.   end  
  112.   
  113.   # PNG文件尾数据块(IEND)
  114.   def make_png_iend
  115.     ie_size = [0].pack("N")
  116.     ie_sign = "IEND"
  117.     ie_crc = [Zlib.crc32(ie_sign)].pack("N")
  118.     return ie_size + ie_sign + ie_crc
  119.   end
  120.   
  121.   # 获取数据
  122.   def get_data
  123.     data = "rgba" * width * height
  124.     RtlMoveMemory_pi.call(data, address, data.length)
  125.     return data
  126.   end
  127. end

  128. #==============================================================================
  129. # Bitmap类修改尝试
  130. #==============================================================================

  131. class Bitmap
  132.   # 取得点(x,y)的颜色(Color)
  133.   def get_pixel_plus(x, y)
  134.     data = "rgba"
  135.     nth = ((height - 1 - y) * width + x) * data.length
  136.     RtlMoveMemory_pi.call(data, address + nth, data.length)   
  137.     clr_ary = data.unpack('c*')
  138.     return Color.new(clr_ary[2],clr_ary[1],clr_ary[0],clr_ary[3])
  139.   end
  140.   
  141.   # 设定点(x,y)的颜色为 color(Color)
  142.   def set_pixel_plus(x, y, color)
  143.     data = [color.blue,color.green,color.red,color.alpha].pack('c*')
  144.     nth = ((height - 1 - y) * width + x) * data.length
  145.     RtlMoveMemory_ip.call(address + nth, data, data.length)
  146.     return self
  147.   end
  148. end

  149. #==============================================================================
  150. # 快速存储Bitmap的Marshal(修改版)By 柳之一
  151. #==============================================================================

  152. class Font
  153.   def marshal_dump;end
  154.   def marshal_load(obj);end
  155. end

  156. class Bitmap
  157.   attr_accessor :address
  158.   
  159.   # API
  160.   RtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
  161.   RtlMoveMemory_ip = Win32API.new('kernel32', 'RtlMoveMemory', 'ipi', 'i')
  162.   
  163.   # Save
  164.   def _dump(limit)
  165.     data = "rgba" * width * height
  166.     RtlMoveMemory_pi.call(data, address, data.length)
  167.     [width, height, Zlib::Deflate.deflate(data)].pack("LLa*") # 压缩
  168.   end
  169.   
  170.   # Read
  171.   def self._load(str)
  172.     w, h, zdata = str.unpack("LLa*"); b = new(w, h)
  173.     RtlMoveMemory_ip.call(b.address, Zlib::Inflate.inflate(zdata), w * h * 4); b
  174.   end
  175.   
  176.   def address
  177.     @address = ini_address if @address.nil?
  178.     return @address
  179.   end
  180.   
  181.   def ini_address
  182.     buffer, ad = "xxxx", object_id * 2 + 16
  183.     RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0] + 8
  184.     RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0] + 16
  185.     RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0]
  186.     return ad
  187.   end
  188. end

  189. #-------------------------------------------------------------------------------
  190. # ■ End of Script
  191. #    本脚本来自66RPG.com  Script form 66RPG.com.
  192. #    严禁用于商业用途    Mustn't be used for commercial/business purpose.
  193. #    转载请保留此信息    Keep this message when repost.
  194. #-------------------------------------------------------------------------------
复制代码
[Ntec]Para_Expander v1.1 第二部分(本体)
  1. #==============================================================================
  2. # ■ [Ntec]Para_Expander (Parallaxes_expander) v1.1
  3. #------------------------------------------------------------------------------
  4. #   将比画面小的远景图居中扩充到画面大小。(在四周添加边框)
  5. #    四周边框的颜色由原图左上角第一个像素的颜色决定。
  6. #-------------------------------------------------------------------------------
  7. #    脚本作者: 各种压力的猫君
  8. #    使用协议: 严禁用于商业用途
  9. #    RGSS版本: RGSS/RGSS2 (Rpg Maker XP/VX)
  10. #    必需脚本: [Ntec]Bitmap2Png v 1.0 以上(原始脚本 by 轮回者 feat 柳之一)
  11. #-------------------------------------------------------------------------------
  12. #    更新记录:
  13. #    ◇2011-12-15 v1.1 by 各种压力的猫君
  14. #    └紧急修正backup目录不存在时报错(现在可以自动生成目录);
  15. #    ◇2011-12-15 v1.0 by 各种压力的猫君
  16. #    └初版;
  17. #-------------------------------------------------------------------------------
  18. #    插入位置:
  19. #      必需脚本之下,尽可能靠近脚本编辑器脚本列表顶端。
  20. #      若要修改分辨率,请在本脚本之前修改。
  21. #    使用方法:
  22. #      ※请先在通用配置模块中配置相应设定※
  23. #      运行游戏即可,执行过程中会弹出提示窗口。
  24. #      成功执行本脚本之后请在通用配置模块中关掉开关或删除本脚本。
  25. #    脚本说明:
  26. #      支持的输入格式有png、bmp、jpg,但都会被输出为png。
  27. #      原始文件会被移动到远景图目录下的backup文件夹中。
  28. #      本脚本为双远景辅助用脚本,其他情况用处不大。
  29. #===============================================================================

  30. #-------------------------------------------------------------------------------
  31. # ▼ Ntec 通用配置模块
  32. #-------------------------------------------------------------------------------

  33. module Ntec
  34.   module Para_Expander
  35.    
  36.     # 远景图目录(为空时自动获取,若未修改默认目录请留空)
  37.     dir = ""
  38.    
  39.     # 画面分辨率(为0时自动获取,若未对默认分辨率做修改此处请保留0)
  40.     screen_width  = 0  # 宽度(如需指定请同时指定高度)
  41.     screen_height = 0  # 高度(如需指定请同时指定宽度)
  42.    
  43. "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
  44. "┃      [Ntec] 自定义内容到此结束,以下内容切勿随意修改      ┃"
  45. "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"

  46.     # 检测运行环境
  47.     if RUBY_VERSION == "1.9.2"
  48.       print "检测到当前运行环境为RGSS3 (Rpg Maker VX Ace)\n" +
  49.             "\n本脚本暂不支持此运行环境\n" +
  50.             "\n按确定键退出"
  51.       exit
  52.     end
  53.     if defined? $TEST
  54.       DIR = "Graphics/Parallaxes/" unless dir != ""
  55.       if screen_width != 0 and screen_height != 0
  56.         SW = screen_width
  57.         SH = screen_height
  58.       else
  59.         SW = Graphics.width
  60.         SH = Graphics.height
  61.       end
  62.       print "检测到当前运行环境为RGSS2 (Rpg Maker VX)\n" +
  63.             "\n分辨率设置为:" + SW.to_s + "×" + SH.to_s + "\n" +
  64.             "远景目录设置为:" + DIR.to_s
  65.     else
  66.       DIR = "Graphics/Panoramas/" unless dir != ""
  67.       if screen_width != 0 and screen_height != 0
  68.         SW = screen_width
  69.         SH = screen_height
  70.       else
  71.         SW = 640
  72.         SH = 480
  73.       end
  74.       print "检测到当前运行环境为RGSS (Rpg Maker XP)" +
  75.              "\n分辨率设置为:" + SW.to_s + "×" + SH.to_s + "\n" +
  76.             "远景目录设置为:" + DIR.to_s
  77.     end
  78.     # 版本号
  79.     VERSION = 1.0
  80.     # 错误时操作
  81.     ON_ERROR = "exit"
  82.     # 检测必需脚本
  83.     unless defined? Ntec::Bitmap2Png::VERSION and
  84.                     Ntec::Bitmap2Png::VERSION >= 1.0
  85.       print "必需脚本[Ntec]Bitmap2Png不存在或版本过低。"
  86.       eval Ntec::Para_Expander::ON_ERROR
  87.     end
  88.   end
  89. end

  90. #-------------------------------------------------------------------------------
  91. # ▼ Parallaxes_expander Class
  92. #-------------------------------------------------------------------------------

  93. class Parallaxes_expander
  94.   
  95.   #--------------------------------------------------------------------------
  96.   # ● 初始化:检测远景图,存入数组
  97.   #--------------------------------------------------------------------------
  98.   
  99.   def initialize
  100.     # 检测远景图,存入数组
  101.     @pnglist = Dir.glob(Ntec::Para_Expander::DIR + "*.png")
  102.     @bmplist = Dir.glob(Ntec::Para_Expander::DIR + "*.bmp")
  103.     @jpglist = Dir.glob(Ntec::Para_Expander::DIR + "*.jpg")
  104.     if @pnglist.size + @bmplist.size + @jpglist.size == 0
  105.       print "没有检测到远近图文件,请确认远景图目录设置正确。"
  106.       eval Ntec::Para_Expander::ON_ERROR
  107.     else
  108.       print "检测到以下格式远景图:\n" +
  109.             @pnglist.size.to_s + "个png格式远景图\n" +
  110.             @bmplist.size.to_s + "个bmp格式远景图\n" +
  111.             @jpglist.size.to_s + "个jpg格式远景图\n" +
  112.             "\n按确定键开始分析 (step 1 of 2)"
  113.       # 转到扫描bitmap尺寸
  114.       scan_bitmap_size
  115.     end
  116.   end
  117.   
  118.   #--------------------------------------------------------------------------
  119.   # ● 扫描bitmap尺寸
  120.   #--------------------------------------------------------------------------
  121.   
  122.   def scan_bitmap_size
  123.     # 初始化数组
  124.     @do_list = []
  125.     # 初始化计数器
  126.     count = 0
  127.     # 处理png格式
  128.     for png in @pnglist
  129.       temp_bitmap = Bitmap.new(png)
  130.       if temp_bitmap.width  < Ntec::Para_Expander::SW or
  131.          temp_bitmap.height < Ntec::Para_Expander::SH
  132.         # 压入数组
  133.         @do_list.push png
  134.       end
  135.       temp_bitmap.dispose
  136.       # 计数器进位
  137.       count += 1
  138.       # 每处理20次回收内存,防止内存溢出
  139.       if count % 20 == 0
  140.         GC.start
  141.       end
  142.     end
  143.     # 处理bmp格式
  144.     for bmp in @bmplist
  145.       temp_bitmap = Bitmap.new(bmp)
  146.       if temp_bitmap.width  < Ntec::Para_Expander::SW or
  147.          temp_bitmap.height < Ntec::Para_Expander::SH
  148.         # 压入数组
  149.         @do_list.push bmp
  150.       end
  151.       temp_bitmap.dispose
  152.       # 计数器进位
  153.       count += 1
  154.       # 每处理20次回收内存,防止内存溢出
  155.       if count % 20 == 0
  156.         GC.start
  157.       end
  158.     end
  159.     # 处理jpg格式
  160.     for jpg in @jpglist
  161.       temp_bitmap = Bitmap.new(jpg)
  162.       if temp_bitmap.width  < Ntec::Para_Expander::SW or
  163.          temp_bitmap.height < Ntec::Para_Expander::SH
  164.         # 压入数组
  165.         @do_list.push jpg
  166.       end
  167.       temp_bitmap.dispose
  168.       # 计数器进位
  169.       count += 1
  170.       # 每处理20次回收内存,防止内存溢出
  171.       if count % 20 == 0
  172.         GC.start
  173.       end
  174.     end
  175.     # 转到处理bitmap
  176.     print "检测到需要处理的远景图" + @do_list.size.to_s + "张\n" +
  177.           "\n处理过程将花费较长时间,请耐心等待。\n" +
  178.           "处理过程中请务必确保本窗口为激活状态,若失去焦点将暂停处理。\n" +
  179.           "\n按确定键开始处理 (step 2 of 2)"
  180.     expand_bitmap
  181.   end
  182.   
  183.   #--------------------------------------------------------------------------
  184.   # ● 扩展bitmap
  185.   #--------------------------------------------------------------------------
  186.   
  187.   def expand_bitmap
  188.     # 记录现在时间
  189.     @begin_time = Time.now
  190.     # 生成底Bitmap
  191.     expanded_width  = Ntec::Para_Expander::SW
  192.     expanded_height = Ntec::Para_Expander::SH
  193.     @expanded_bitmap = Bitmap.new(expanded_width, expanded_height)
  194.     @expanded_rect   = @expanded_bitmap.rect
  195.     # 初始化计数器
  196.     count = 0
  197.     @count = 0
  198.     # 主循环,处理bitmap
  199.     for bitmap in @do_list
  200.       # 读入待处理bitmap
  201.       small_bitmap = Bitmap.new(bitmap)
  202.       small_width  = small_bitmap.width
  203.       small_height = small_bitmap.height
  204.       src_rect = small_bitmap.rect
  205.       small_x = (expanded_width - small_width) / 2
  206.       small_y = (expanded_height - small_height) /2
  207.       # 生成输出bitmap
  208.       new_bitmap = @expanded_bitmap.clone
  209.       expanded_color = small_bitmap.get_pixel(0, 0)
  210.       new_bitmap.fill_rect(@expanded_rect, expanded_color)
  211.       new_bitmap.blt(small_x, small_y, small_bitmap, src_rect)
  212.       # 储存bitmap
  213.       save_bitmap(new_bitmap, bitmap)
  214.       new_bitmap.dispose
  215.       # 计数器进位
  216.       count += 1
  217.       # 每处理20次回收内存,防止内存溢出
  218.       if count % 20 == 0
  219.         GC.start
  220.       end
  221.     end
  222.     # 转到处理完成
  223.     expand_done
  224.   end
  225.   
  226.   #--------------------------------------------------------------------------
  227.   # ● 储存bitmap
  228.   #--------------------------------------------------------------------------
  229.   
  230.   def save_bitmap(bitmap, filename)
  231.     # 生成文件名
  232.     dirname  = File.dirname(filename)
  233.     basename = File.basename(filename)
  234.     savename = File.basename(filename, ".*")
  235.     backupdir = dirname + "/backup/"
  236.     backupname = backupdir + basename
  237.     createname = dirname + "/" + savename + ".png"
  238.     # 生成备份目录
  239.     Dir.mkdir(backupdir) unless FileTest.exist?(backupdir)
  240.     # 备份原文件
  241.     File.rename(filename, backupname)
  242.     # 储存新文件
  243.     bitmap.save2png(createname)
  244.     # 计数器进位
  245.     @count += 1
  246.   end

  247.   #--------------------------------------------------------------------------
  248.   # ● 处理完成
  249.   #--------------------------------------------------------------------------
  250.   
  251.   def expand_done
  252.     time = Time.now - @begin_time
  253.     print "处理完成\n共处理:" + @count.to_s + "张远景图,\n" +
  254.           "耗时:" + time.to_s + "秒\n" +
  255.           "\n 按确定键退出"
  256.     exit
  257.   end
  258.   
  259. end

  260. #-------------------------------------------------------------------------------
  261. # ▼ Run Script
  262. #-------------------------------------------------------------------------------

  263. Parallaxes_expander.new

  264. #-------------------------------------------------------------------------------
  265. # ■ End of Script
  266. #    本脚本来自66RPG.com  Script form 66RPG.com.
  267. #    严禁用于商业用途    Mustn't be used for commercial/business purpose.
  268. #    转载请保留此信息    Keep this message when repost.
  269. #-------------------------------------------------------------------------------
复制代码
使用说明:
将第一个脚本放置于脚本编辑器顶端,第二个脚本放置于其下,保存并运行游戏即可。
生成完毕后删除两个脚本即可。

紧急修正:
请手工在远景图目录下新建backup文件夹,否则脚本可能报错。
↑v1.1已紧急修正。

范例工程:
暂不提供
作者: 阿尔西斯的马甲    时间: 2011-12-18 10:05
不明白这脚本到底是什么用处




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1