じ☆ve冰风 发表于 2024-4-19 16:29:23

PNG文件输出[发布预备]

#==============================================================================# PNG文件输出#   用法:bitmap.save2png(filename)# BY:轮回者#==============================================================================class Bitmap      # 是否自动颠倒上下?#   false时输出图像上下会颠倒,但并不能节省很多时间SWITCH_UP2DOWN = true    # 存入PNG文件def save2png(filename)    file = File.open(filename,"wb")    file.write(make_png_header)    file.write(make_png_ihdr)    file.write(make_png_idat)    file.write(make_png_iend)    file.closeend    # PNG文件头数据块def make_png_header    return .pack("C*")end# PNG文件情报头数据块(IHDR)def make_png_ihdr    ih_size = .pack("N")    ih_sign = "IHDR"    ih_width = .pack("N")    ih_height = .pack("N")    ih_bit_depth = .pack("C")    ih_color_type = .pack("C")    ih_compression_method = .pack("C")    ih_filter_method = .pack("C")    ih_interlace_method = .pack("C")    string = ih_sign + ih_width + ih_height + ih_bit_depth + ih_color_type +            ih_compression_method + ih_filter_method + ih_interlace_method    ih_crc = .pack("N")    return ih_size + string + ih_crcend    # PNG图像数据(IDAT)def make_png_idat    header = "\x49\x44\x41\x54"    data = SWITCH_UP2DOWN ? make_png_data : make_png_data2    data = Zlib::Deflate.deflate(data, 8)    crc = .pack("N")    size = .pack("N")    return size + header + data + crcend    # PNG图像数据(点阵);自动颠倒上下def make_png_data    data = get_data.unpack('x2aX2aX2ax2a'*height*width).to_s    len = width * 4          for y in 0...height      break if 2*y >= height - 1      nth1 = y * len            nth2 = (height - 1 - y) * len            tStr = data            data = data            data = tStr    end      for y in 0...height      nth = (height - 1 - y) * width * 4      data.insert(nth,"\000")    end    return dataend    # PNG图像数据(点阵);不自动颠倒上下def make_png_data2    data = get_data.unpack('x2aX2aX2ax2a'*height*width).to_s    for y in 0...height      nth = (height - 1 - y) * width * 4      data.insert(nth,"\000")    end    return dataend      # PNG文件尾数据块(IEND)def make_png_iend    ie_size = .pack("N")    ie_sign = "IEND"    ie_crc = .pack("N")    return ie_size + ie_sign + ie_crcend    # 获取数据def get_data    data = "rgba" * width * height    RtlMoveMemory_pi.call(data, address, data.length)    return dataendend#==============================================================================# Bitmap类修改尝试#==============================================================================class Bitmap# 取得点(x,y)的颜色(Color)def get_pixel_plus(x, y)    data = "rgba"    nth = ((height - 1 - y) * width + x) * data.length    RtlMoveMemory_pi.call(data, address + nth, data.length)      clr_ary = data.unpack('c*')    return Color.new(clr_ary,clr_ary,clr_ary,clr_ary)end    # 设定点(x,y)的颜色为 color(Color)def set_pixel_plus(x, y, color)    data = .pack('c*')    nth = ((height - 1 - y) * width + x) * data.length    RtlMoveMemory_ip.call(address + nth, data, data.length)    return selfendend#==============================================================================# 快速存储Bitmap的Marshal(修改版)By 柳之一#==============================================================================class Fontdef marshal_dump;enddef marshal_load(obj);endendclass Bitmapattr_accessor :address# 初始化传送到内存的API函数RtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')RtlMoveMemory_ip = Win32API.new('kernel32', 'RtlMoveMemory', 'ipi', 'i')    # 保存def _dump(limit)    data = "rgba" * width * height    RtlMoveMemory_pi.call(data, address, data.length)    .pack("LLa*") # 压缩end    # 读取def self._load(str)    w, h, zdata = str.unpack("LLa*"); b = new(w, h)    RtlMoveMemory_ip.call(b.address, Zlib::Inflate.inflate(zdata), w * h * 4); bend    # [[ + 8] + 16] == 数据的开头#def address    @address = ini_address if @address.nil?    return @addressend    def ini_address    buffer, ad = "xxxx", object_id * 2 + 16    RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L") + 8    RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L") + 16    RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")    return adendend#==============================================================================# 回收站~#===============================================================================beginclass Color_Plus# 初始化实例变量attr_accessor :redattr_accessor :greenattr_accessor :blueattr_accessor :alpha# 初始化def initialize(red, green, blue, alpha=255)    @red   = red    @green = green    @blue= blue   @alpha = alphaend    # 设定所有属性def set(red, green, blue, alpha=255)    @red   = red    @green = green    @blue= blue   @alpha = alphaendend=end复制代码用到了某柳的东西,感觉轮子这个还是不错的{/hx}
             本帖来自P1论坛作者小传子,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=89989若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页: [1]
查看完整版本: PNG文件输出[发布预备]