mini_magickとImageMagickで画像を切り取る
capybara-webkitで撮影した縦長のwebページスクリーンショット(PNG)を、1:1.41のA4縦長で印刷できるサイズ(JPEG)に分割する。
brew install imagemagick gem install mini_magick
mini_magick版
#!/usr/bin/env ruby require 'rubygems' require 'mini_magick' source = ARGV.shift img = MiniMagick::Image.open source puts "#{img[:width]}x#{img[:height]}" w = img[:width] h = (w*1.41).to_i 0.upto(img[:height]/h) do |i| puts fname = "#{i}.jpg" img = MiniMagick::Image.open source img.format('jpg') img.quality('95') img.crop("#{w}x#{h}+0+#{i*h}") img.write(fname) end
結果
1236x8026 0.jpg 1.jpg 2.jpg 3.jpg 4.jpg ruby crop.rb ../capybara-screenshot/shokai.png 7.73s user 1.82s system 89% cpu 10.663 total
7.73秒かかった。
ImageMagickはファイルにあわせて画像フォーマットを決めてくれるのに、mini_magickではformatメソッドで指定しないと元画像のままPNG形式で保存されてしまっていた。
exiftoolで確認すべき。
ImageMagick版
#!/usr/bin/env ruby img = ARGV.shift width, height = `identify '#{img}'`.split(/\s/).select{|i| i =~ /^\d+x\d+$/ }.first.split('x').map{|i| i.to_i} puts "#{width}x#{height}" w = width h = (w*1.41).to_i 0.upto(height/h) do |i| puts fname = "#{i}.jpg" puts cmd = "convert -quality 95 -crop #{w}x#{h}+0+#{h*i} #{img} #{fname}" system cmd end
結果
0.jpg convert -crop 1236x1742+0+0 ../capybara-screenshot/shokai.png 0.jpg 1.jpg convert -crop 1236x1742+0+1742 ../capybara-screenshot/shokai.png 1.jpg 2.jpg convert -crop 1236x1742+0+3484 ../capybara-screenshot/shokai.png 2.jpg 3.jpg convert -crop 1236x1742+0+5226 ../capybara-screenshot/shokai.png 3.jpg 4.jpg convert -crop 1236x1742+0+6968 ../capybara-screenshot/shokai.png 4.jpg ruby crop_imagemagick.rb ../capybara-screenshot/shokai.png 1.97s user 0.52s system 74% cpu 3.089 total
1.97秒だった。
ImageMagickを直に使ったほうが圧倒的に速い。
感想
- ImageMagickを直に使ったほうが速い。しかし・・
- 画像のサイズやフォーマットなどを読み取る場合、identifyコマンドを使うのだが文字列で返ってくるのでparseが面倒。mini_magickやrmagickを使ったほうが楽。
- 画像のサイズを変えたり、色調を補正するぐらいならImageMagickをそのまま使ったほうが楽だし、高速。
- 特に細かいオプションを設定したりする場合、それをラッパーから指定する方法を調べるのがめんどい。
- 複数の画像を重ねあわせたりするならmini_magickなどを使ったほうが書きやすい。
使い分け
ちょっと画像を加工→ImageMagickを直に使う
画像のプロパティを読み取り、細かくに加工(というか装飾)→mini_magick
がいいのでは。