以下のような正確な png ファイルを
16×16 のタイルに分割して
以下のようなタイルを生成します。
ファイル名は 0.png, 1.png, 2.png 等になります。
同時に、どのタイルがどの部分に対応するかをしめす
csv も生成します。
csvのイメージ
(例えば64×64のイメージの場合 3×3 のタイルになる)
1, 2, 0 0, 0, 1 1, 1, 1
Ruby から ImageMagick を扱うためのライブラリ
RMagick を使用します。
RMagick のインストール(macOS)
% brew install imagemagick % brew install pkg-config % sudo gem install rmagick
実行方法
分割したいファイルを指定して以下のように
実行します。
% ruby divide_into_tile.rb hoge.rb
成功すると
output/*.png
tilemap.csv
が生成されます。
Ruby スクリプトは以下のようになります。
divide_into_tile.rb
require "RMagick" require "csv" require "fileutils" include Magick filename = ARGV[0] unless filename puts "please set input image filename" puts "ex. % ruby divide_into_tile.rb hoge.jpg" exit end unless File.exist?(filename) puts "no such file #{filename}" exit end image_load = ImageList.new(filename) # image_load = Magick::Image.read('field.png').first width = image_load.columns height = image_load.rows puts " width #{width}" puts " height #{height}" sprite_x_count = width / 16 sprite_y_count = height / 16 tile_count = 0 FileUtils.mkdir_p("output") metric = Magick::PeakSignalToNoiseRatioErrorMetric tilemap_csv = CSV.open('tilemap.csv','w') for num_y in 0 .. sprite_y_count - 1 do pos_y = num_y * 16 array = [] for num_x in 0..sprite_x_count - 1 do pos_x = num_x * 16 # puts " " # puts "------------" puts "analysing x #{num_x} / #{sprite_x_count - 1}, y: #{num_y} / #{sprite_y_count - 1}" image_cropped = image_load.crop(pos_x, pos_y, 16, 16) if tile_count == 0 image_name = "#{tile_count}.png" # puts "writing #{image_name}" image_cropped.write("output/#{image_name}") array.append(0) tile_count += 1 else # 過去に同じのないかチェック is_matched = false for num_tile in 0 .. tile_count - 1 do image_tile_name = "#{num_tile}.png" image_tile = ImageList.new("output/#{image_tile_name}") diff = image_cropped.compare_channel(image_tile, metric)[1] # puts "check match diff #{diff}" if diff == Float::INFINITY # puts "matched" is_matched = true array.append(num_tile) break end end unless is_matched # 一個もマッチしない image_name = "#{tile_count}.png" # puts "writing #{image_name}" image_cropped.write("output/#{image_name}") array.append(tile_count) tile_count += 1 end end end tilemap_csv.puts array end tilemap_csv.close
コメント