[XP][VX] Animation Sheet Maker

Started by Fantasist, March 10, 2009, 03:53:34 pm

Previous topic - Next topic

Fantasist

March 10, 2009, 03:53:34 pm Last Edit: March 10, 2009, 04:03:51 pm by Blizzard
Animation Sheet Maker
Authors: Fantasist, www.66rpg.com
Version: 1.0
Type: Resource Utility
Key Term: Game Utility



Introduction

This script can read image files from a folder and compile them into an animation sheet for use with RMXP and RMVX.


Features


  • Easy to use.
  • Handles transparency.
  • Saves a lot of time while making animations.



Screenshots

N/A


Download

http://www.sendspace.com/file/6rq31f (924 KB)


Script

Put the script at the very top of all the scripts.
Spoiler: ShowHide

#==============================================================================
# ** Animation Sheet Maker
#------------------------------------------------------------------------------
# by Fantasist
# Version: 1.0
# Date: 11-Mar-2009
#------------------------------------------------------------------------------
# Version History:
#
#   1.0 - First version
#------------------------------------------------------------------------------
# Description:
#
#     This script can read image files from a folder and compile them into an
#   animation sheet for use with RMXP/RMVX.
#------------------------------------------------------------------------------
# Compatibility:
#
#   Needs file writing permissions to save the temporary and output files.
#------------------------------------------------------------------------------
# Instructions:
#
#    - Put all the frames of one animation in a folder and paste it in the
#      program's directory.
#    - Include the names of the folders in quotes in the "Config.txt" file.
#    - Run "MakeAnimSheet.exe" and wait.
#
#   NOTE: The contents of Config.txt will be directly loaded, so do not make
#         errors of any sort. Include the folder names in the "List" array.
#
#   Example:
#
#         List = [ 'Animation1', 'folder2', 'anim' ]
#------------------------------------------------------------------------------
# Issues:
#
#     If this script is used with RMXP, there is a chance of the game freezing
#   with a "Script is hanging" error. Use this with RMVX to avoid the problem.
#------------------------------------------------------------------------------
# Credits and Thanks:
#
#   Fantasist - For making this.
#   www.66rpg.com - For the PNG output script.
#   Viviatus - For requesting this.
#------------------------------------------------------------------------------
# Notes:
#
#     You should find the program where you found this script. It is
#   recommended that you use the program, since it is minimal and prevents a
#   possible crash (when used in RMXP).
#
#   If you have any questions, suggestions or comments, you can find me at:
#
#    - www.chaos-project.com
#    - www.quantumcore.forumotion.com
#
#   Enjoy ^_^
#==============================================================================
#==============================================================================
#               本脚本出自www.66rpg.com,转载请注明。
#==============================================================================
=begin
==============================================================================
                        Bitmap to PNG By 轮回者
==============================================================================

对Bitmap对象直接使用

bitmap_obj.make_png(name[, path])

name:保存文件名
path:保存路径

感谢66、夏娜、金圭子的提醒和帮助!
   
==============================================================================
=end

module Zlib
  class Png_File < GzipWriter
    #--------------------------------------------------------------------------
    # ● 主处理
    #--------------------------------------------------------------------------
    def make_png(bitmap_Fx,mode)
      @mode = mode
      @bitmap_Fx = bitmap_Fx
      self.write(make_header)
      self.write(make_ihdr)
      self.write(make_idat)
      self.write(make_iend)
    end
    #--------------------------------------------------------------------------
    # ● PNG文件头数据块
    #--------------------------------------------------------------------------
    def make_header
      return [0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a].pack("C*")
    end
    #--------------------------------------------------------------------------
    # ● PNG文件情报头数据块(IHDR)
    #--------------------------------------------------------------------------
    def make_ihdr
      ih_size = [13].pack("N")
      ih_sign = "IHDR"
      ih_width = [@bitmap_Fx.width].pack("N")
      ih_height = [@bitmap_Fx.height].pack("N")
      ih_bit_depth = [8].pack("C")
      ih_color_type = [6].pack("C")
      ih_compression_method = [0].pack("C")
      ih_filter_method = [0].pack("C")
      ih_interlace_method = [0].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 = [Zlib.crc32(string)].pack("N")
      return ih_size + string + ih_crc
    end
    #--------------------------------------------------------------------------
    # ● 生成图像数据(IDAT)
    #--------------------------------------------------------------------------
    def make_idat
      header = "\x49\x44\x41\x54"
      case @mode # 请54~
      when 1
        data = make_bitmap_data#1
      else
        data = make_bitmap_data
      end
      data = Zlib::Deflate.deflate(data, 8)
      crc = [Zlib.crc32(header + data)].pack("N")
      size = [data.length].pack("N")
      return size + header + data + crc
    end
    #--------------------------------------------------------------------------
    # ● 从Bitmap对象中生成图像数据 mode 1(请54~)
    #--------------------------------------------------------------------------
    def make_bitmap_data1
      w = @bitmap_Fx.width
      h = @bitmap_Fx.height
      data = []
      for y in 0...h
        data.push(0)
        for x in 0...w
          color = @bitmap_Fx.get_pixel(x, y)
          red = color.red
          green = color.green
          blue = color.blue
          alpha = color.alpha
          data.push(red)
          data.push(green)
          data.push(blue)
          data.push(alpha)
        end
      end
      return data.pack("C*")
    end
    #--------------------------------------------------------------------------
    # ● 从Bitmap对象中生成图像数据 mode 0
    #--------------------------------------------------------------------------
    def make_bitmap_data
      gz = Zlib::GzipWriter.open('hoge.gz')
      t_Fx = 0
      w = @bitmap_Fx.width
      h = @bitmap_Fx.height
      data = []
      for y in 0...h
        data.push(0)
        for x in 0...w
          t_Fx += 1
          if t_Fx % 10000 == 0
            Graphics.update
          end
          if t_Fx % 100000 == 0
            s = data.pack("C*")
            gz.write(s)
            data.clear
            #GC.start
          end
          color = @bitmap_Fx.get_pixel(x, y)
          red = color.red
          green = color.green
          blue = color.blue
          alpha = color.alpha
          data.push(red)
          data.push(green)
          data.push(blue)
          data.push(alpha)
        end
      end
      s = data.pack("C*")
      gz.write(s)
      gz.close   
      data.clear
      gz = Zlib::GzipReader.open('hoge.gz')
      data = gz.read
      gz.close
      File.delete('hoge.gz')
      return data
    end
    #--------------------------------------------------------------------------
    # ● PNG文件尾数据块(IEND)
    #--------------------------------------------------------------------------
    def make_iend
      ie_size = [0].pack("N")
      ie_sign = "IEND"
      ie_crc = [Zlib.crc32(ie_sign)].pack("N")
      return ie_size + ie_sign + ie_crc
    end
  end
end
#==============================================================================
# ■ Bitmap
#------------------------------------------------------------------------------
#  关联到Bitmap。
#==============================================================================
class Bitmap
  #--------------------------------------------------------------------------
  # ● 关联
  #--------------------------------------------------------------------------
  def make_png(name="like", path="",mode=0)
    make_dir(path) if path != ""
    Zlib::Png_File.open("temp.gz") {|gz|
      gz.make_png(self,mode)
    }
    Zlib::GzipReader.open("temp.gz") {|gz|
      $read = gz.read
    }
    f = File.open(path + name + ".png","wb")
    f.write($read)
    f.close
    File.delete('temp.gz')
    end
  #--------------------------------------------------------------------------
  # ● 生成保存路径
  #--------------------------------------------------------------------------
  def make_dir(path)
    dir = path.split("/")
    for i in 0...dir.size
      unless dir == "."
        add_dir = dir[0..i].join("/")
        begin
          Dir.mkdir(add_dir)
        rescue
        end
      end
    end
  end
end
#==============================================================================
#               本脚本出自www.66rpg.com,转载请注明。
#==============================================================================
#==============================================================================
# ** AnimSheetMaker
#==============================================================================
module AnimSheetMaker
  module_function
  #--------------------------------------------------------------------------
  # * Define constants
  #--------------------------------------------------------------------------
  SCREEN_WIDTH = 544
  SCREEN_HEIGHT = 416
  FRAME_SIZE = 192
  #--------------------------------------------------------------------------
  # * Make a sprite and center it
  #--------------------------------------------------------------------------
  @sprite = Sprite.new
  @sprite.x = SCREEN_WIDTH / 2
  @sprite.y = SCREEN_HEIGHT / 2
  #--------------------------------------------------------------------------
  # * Make Sheet
  #--------------------------------------------------------------------------
  def make_sheet(foldername)
    # Collect the files to be processed
    files = []
    Dir.foreach(foldername) {|filename|
    files.push(filename) if File.extname(filename).downcase == '.png'}
    # Make the sheet
    sheet_width = (files.size > 6 ? 5 : files.size) * FRAME_SIZE
    sheet_height = (files.size / 5 + 1) * FRAME_SIZE
    sheet = Bitmap.new(sheet_width, sheet_height)
    # Load each frame
    files.each_with_index {|filename, i|
    frame = Bitmap.new("#{foldername}/#{filename}")
    # Display current image
    set_sprite(frame)
    # Calculate frame offset and paste it on the sheet
    x = (i % 5) * FRAME_SIZE
    y = (i / 5) * FRAME_SIZE
    sheet.blt(x, y, frame, Rect.new(0, 0, FRAME_SIZE, FRAME_SIZE))
    # Dispose frame from memory
    frame.dispose}
    # Display current image
    set_sprite(sheet)
    # Output the sheet
    dirs = foldername.split('/')
    sheet.make_png(dirs[dirs.size - 1])
  end
  #--------------------------------------------------------------------------
  # * Set Sprite
  #--------------------------------------------------------------------------
  def set_sprite(bitmap=nil)
    @sprite.bitmap = bitmap
    return if bitmap.nil?
    # Center the image
    @sprite.ox = bitmap.width / 2
    @sprite.oy = bitmap.height / 2
    # Reduce size if width is larger than screen width
    if bitmap.width > SCREEN_WIDTH
      @sprite.zoom_x = SCREEN_WIDTH.to_f / bitmap.width
    end
    # Reduce size if height is larger than screen height
    if bitmap.height > SCREEN_HEIGHT
      @sprite.zoom_y = SCREEN_HEIGHT.to_f / bitmap.height
    end
    # Apply the lowest zoom (to maintain aspect ratio)
    if @sprite.zoom_x < @sprite.zoom_y
      @sprite.zoom_y = @sprite.zoom_x
    else
      @sprite.zoom_x = @sprite.zoom_y
    end
    # Update the screen
    Graphics.update
  end
  #--------------------------------------------------------------------------
  # * Load Config
  #--------------------------------------------------------------------------
  def load_config
    # Load the configuration file
    IO.readlines('Config.txt').each {|s| eval(s)}
  end
  #--------------------------------------------------------------------------
  # * Run the process
  #--------------------------------------------------------------------------
  # Load list of sheets to make
  start_time = Time.now
  load_config
  # Make the sheets
  List.each {|foldername| make_sheet(foldername)}
  # Shut down
  print "Completed in #{Time.now - start_time} seconds."
  exit
end



Instructions


  • Put all the frames of one animation in a folder and paste it in the program's directory.
  • Include the names of the folders in quotes in the "Config.txt" file.
  • Run "MakeAnimSheet.exe" and wait.


NOTE: The contents of Config.txt will be directly loaded, so do not make errors of any sort. Include the folder names in the "List" array.

Example:
               List = [ 'Animation1', 'folder2', 'anim' ]


Compatibility

Needs file writing permissions to save the temporary and output files.


Credits and Thanks


  • Fantasist - For making this.
  • www.66rpg.com - For the PNG output script.
  • Viviatus - For requesting this.



Author's Notes

You should find the program where you found this script. It is recommended that you use the program, since it is minimal and prevents a possible crash (when this script is used in RMXP).

If you have any questions, suggestions or comments, you can find me at:

- www.chaos-project.com
- www.quantumcore.forumotion.com

Enjoy ^_^
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Calintz


Reno-s--Joker

More than very intriguing - this could be very useful! :D

... YES!!! I found a worship smiley! Perfect... :shifty:
:bow: :bow: :bow:

Viviatus

It IS useful. For me at least...

Thanks again!

Punn


Yin

You don't know how useful this is for me! Thanks!
Newly formed MUGEN, RPG Maker, and BOR forum.
http://cavernofcreativity.com
Opening in September
My Partner in crime = TREXRELL

Axerax

I tried using this. It made faulty errors on the animation. It put the last 3 frames in the middle of the 1st and 2nd frames. Just want you to know.

Aqua


Axerax

Yes I did, 1-12 in the order I wanted them. I even did it 3 times to make sure.

Aqua

Are they all the right size of 192x192?

I've done 115 frames without any problems...

G_G

fantasist heres an idea, you should make it so it places it every 192 pixels instead of right after the first image just to make things easier

Axerax

Quote from: Aqua on September 18, 2009, 09:04:41 pm
Are they all the right size of 192x192?

I've done 115 frames without any problems...


Yes, I tried it the first time without it being like that, but it made it 192x192 squares anyways. 2nd two times I put them on a 192x192 square, still same problem.

I made it my self after much frustration, I just wanted to see if it worked. It apparently hates me.

Fantasist

How did I miss this? Sorry, I'l check it out. Could you give me the original image and the output image?
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




legacyblade

I ran into the same problem, so Axerax is not the only one getting that problem.

Fantasist

QuoteI tried using this. It made faulty errors on the animation. It put the last 3 frames in the middle of the 1st and 2nd frames. Just want you to know.
......
Yes I did, 1-12 in the order I wanted them. I even did it 3 times to make sure.


OK, I just realized something. I misread the post, I thought the script messed with the images, not the placement. It happens because 1 to 12 are sorted as: 1, 10, 11, 12, 2, 3, 4, 5, 6, 7, 8, ,9. It's the way the Dir.foreach method reads the files. It's not really a major problem. To fix it, name the files like this: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12. It's not really much of a problem imo ^_^
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews