搜索附件  

ImageEx: ImageEx_rmxp.zip

 

ImageEx:
感觉很鸡肋,电脑里扔了2个多月,毕竟都写了,发贴混点经验。
ImageEx_rmxp.dll  VS2015  C++语言编写(因为有库是C++的,其实都是按C写的)。


RUBY 代码
[code]module ImageEx
  dll = "ImageEx_rmxp.dll"

  # ———— png 与 jpeg ——————————————————
  # 仅支持 jpeg(Gray/RGB)、png(Gray/GrayAlpha/RGB/RGBA)
  # 使用libjpeg/libpng
  # ————————————————————————————

  # 支持的模式会转换至BGRA,不支持的模式会返回-1。
  # filename_uft8, bitmap_obj_id
  Load_JPG = Win32API.new(dll, 'bitmap_load_jpg', 'PL', 'L')
  # filename_utf8, bitmap_obj_id
  # channels  1或3    BGRA会转换至支持的对应模式
  # quality   0..100  质量越好,文件越大
  Save_JPG = Win32API.new(dll, 'bitmap_save_to_jpg', 'PLLL', 'L')

  # 支持的模式会转换至BGRA,不支持的模式无效操作。
  # filename_uft8, bitmap_obj_id
  Load_PNG = Win32API.new(dll, 'bitmap_load_png', 'PL', 'L')
  # filename_utf8, bitmap_obj_id
  # channels  1..4  BGRA会转换至支持的对应模式
  Save_PNG = Win32API.new(dll, 'bitmap_save_to_png', 'PLL', 'L')


  # ———— gif 与 webp ——————————————————————————
  # 仅支持读取,无论是否使用线程(Win32 CreateThread)都需要释放(调用dispose)
  # gif中disposal_method不支持DISPOSE_PREVIOUS
  # 播放效果视文件而定,可能会“画面闪烁”
  # 效率:非线程模式,640*480大小,读取一帧 gif:1000次/秒 webp:300次/秒
  #            参照,640*480大小的Bitmap#blt    260+次/秒         
  # 使用libgif/libwebp
  # ————————————————————————————————————

  # filename_utf8   : utf8编码的文件名。
  # sprite_obj_id   : RMXP 精灵(Sprite) 对象的 object_id,精灵需设置好其位图。
  # gif_cell_string : GIF_CELL_SIZE字节的字符串,用来保存一些数据。
  # play_mode : 0..3位 是否抠图。抠图效果不错,对效率影响不大。      
  #                    1:抠除黑色;2:抠除白色;其他(0/3):原图。
  #             4..7位 是否线程模式。  0:不使用;非0:使用。
  # loop_count : 自定义播放次数。 0:文件默认次数;负数:一直播放;正数:指定次数。
  Show_GIF = Win32API.new(dll, 'show_gif', 'PLPLL', 'L')
  Draw_GIF = Win32API.new(dll, 'draw_gif', 'L', 'L')
  Free_GIF = Win32API.new(dll, 'free_gif', 'L', 'L')  
  GIF = 0x666967
  GIF_CELL_SIZE = Show_GIF.call(nil, 0, 0, 0, 0)

  # 参数四 mode : 是否线程模式。  0:不使用;非0:使用。
  # 其余参数,参见Show_GIF
  Show_WEBP = Win32API.new(dll, 'show_webp', 'PLPLL', 'L')
  Draw_WEBP = Win32API.new(dll, 'draw_webp', 'L', 'L')
  Free_WEBP = Win32API.new(dll, 'free_webp', 'L', 'L')  
  WEBP = 0x70626577
  WEBP_CELL_SIZE = Show_WEBP.call(nil, 0, 0, 0, 0)

  # 这两个方法其实没什么用……
  defself.get_png_wh(filename)
    w = h = 0
    File.open(filename, 'rb')do |f|
      if f.read(8) == "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A"
        f.seek(8, IO::SEEK_CUR)
        w, h = f.read(8).unpack('NN')
      end
    end
    return w, h
  end

  defself.get_jpg_wh(filename)
    w = h = 0
    File.open(filename, 'rb')do |f|
      if f.read(2) == "\xFF\xD8"
        sof0 = "\xFF\xC0"
        while(buf = f.read(2)) != sof0
          size = f.read(2).unpack('n')
          f.seek(size - 2, IO::SEEK_CUR)
        end
        f.seek(3, IO::SEEK_CUR)
        h, w = f.read(4).unpack('nn')
      end
    end
    return w, h
  end
end


class Bitmap
  def to_int
    self.__id__
  end

  def save_jpg(filename, channels = 3, quality = 90)
    ImageEx::Save_JPG.call(filename, self, channels, quality)
  end

  def save_png(filename, channels = 4)
    ImageEx::Save_PNG.call(filename, self, channels)
  end

  # 读取图片至位图,主要是同样大小的单帧静态图片的动画,避免重复新建Bitmap  
  def load_jpg(filename)
    ImageEx::Load_JPG.call(filename, self)
  end

  def load_png(filename)
    ImageEx::Load_PNG.call(filename, self)
  end   
end

# GifSprite/WebpSprite并没打算复用,用完就释放掉,再新建
class GifSprite < Sprite

  def initialize(filename, mode = 0, loop_count = 0, viewport = nil)

    w = h = 0
    File.open(filename, "rb")do |f|
      if(f.read(6) =~ /GIF8[79]a/)
        w, h = f.read(4).unpack('SS')
      end
    end

    if w == 0 || h == 0
      raise"#{self.class} ERR: #{filename} 可能不是 gif 图片"
    end

    super(viewport)

    self.bitmap = Bitmap.new(w, h)
    self.instance_evaldo
      def bitmap=(obj)
      end
    end

    self.bitmap.instance_evaldo
      alias:dispose_ori:dispose
      def dispose(tag = 0)
        dispose_ori if tag == ImageEx::GIF
      end
    end

    @cell = "\0" * ImageEx::GIF_CELL_SIZE
    err = ImageEx::Show_GIF.call(filename, self.__id__, @cell.__id__,
      mode, loop_count)

    case err
    when-1   thenraise"#{self.class} ERR: 打开 #{filename} 文件失败"
    when-2   thenraise"#{self.class} ERR: 位图 与 #{filename} 不符"
    when-3   thenraise"#{self.class} ERR: @cell 参数不符合要求"
    when-100thenraise"#{self.class} ERR: 解析 #{filename} 失败"
    when-101thenraise"#{self.class} ERR: 内存不足"
    end

    @cell_ptr = [@cell].pack('p').unpack('L')[0]
    @cell.freeze

    @use_thread = (mode & 0xF0 != 0) && (err != -99)
    @delay = 0
    @loop_over = false
  end

  def over?
    return@loop_overif@use_thread == false
    i, c = @cell.unpack('@16LL')
    return c != 0 && i >= c
  end

  def update_frame
    returnif(@loop_over | @use_thread) == true
    returnif(self.disposed? | self.bitmap.disposed?) == true
    returnifself.visible == false || self.opacity == 0

    if@delay > 0
      @delay -= 1
    else
      ms = ImageEx::Draw_GIF.call(@cell_ptr)
      if ms < 0
        @loop_over = true
      else
        @delay = (ms * Graphics.frame_rate + 999) / 1000
      end
    end
  end

  def dispose
    returnifself.disposed? == true
    ImageEx::Free_GIF.call(@cell_ptr)
    self.bitmap.dispose(ImageEx::GIF)
    super
  end
end


class WebpSprite < Sprite

  def initialize(filename, mode = 0, loop_count = 0, viewport = nil)

    w = h = 0
    File.open(filename, "rb")do |f|
      if(f.read(4) == "RIFF")
        f.seek(4, IO::SEEK_CUR)

        if(f.read(4) == "WEBP")        
          chunk = f.read(4)
          f.seek(4, IO::SEEK_CUR)

          if(chunk == "VP8 ")
            if(f.read(1).unpack('C')[0][0] == 0)
              f.seek(2, IO::SEEK_CUR)
              if(f.read(3) == "\x9D\x01\x2A")
                w, h = f.read(4).unpack('SS')
              end
            end
          elsif(chunk == "VP8L")
            f.seek(1, IO::SEEK_CUR)
            n = f.read(4).unpack('L')[0]

            w = (n & 0x3FFF) + 1
            h = ((n & 0xFFFC000) >> 14) + 1
          elsif(chunk == "VP8X")
            f.seek(4, IO::SEEK_CUR)

            w, w16, h, h16 = f.read(6).unpack('SCSC')
            w += (w16
关闭

幸运抽奖

社区每日抽奖来袭,快来试试你是欧皇还是非酋~

立即查看

Loading...

QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

GMT+8, 2024-11-25 12:03 , Processed in 0.051475 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

返回顶部