minimagickのソースを読む

※ 記事執筆時点のversionは4.9.2です。

minimagickの内部の動作の理解のためにソースを読んでみた。
今回はminimagickのクラス構成と役割を調べてみる。

以下クラス構成

  • MiniMagick
    • Configuration
    • Image
      • Info
    • Shell
    • Tool
      • Animate
      • Compare
      • Composite
      • Conjure
      • Convert
      • Display
      • Identify
      • Import
      • Magick
      • MogrifyRestricted
      • Mogrify
      • Montage
      • Stream
    • Utilities
    • VERSION

各クラスの役割をざっくり解説していく

Image

画像ファイルの読み込みから各クラスのメソッドを使う為の基点となるクラス。
画像の加工、書き出しまで基本このクラスで行う。

image = Magick::Image.read(file)

Magick::Image.readはインスタンス作成時にtempfileを使ってファイルのコピーを作成して使うため、
元画像には影響を与えない。

未定義のメソッドはmethod_missingを利用してMogrifyに処理が渡される。

def method_missing(name, *args)
  mogrify do |builder|
    builder.send(name, *args)
  end
end

# example
# Imageクラスはresizeメソッドを持ってない
image.resize "100x100"

Tool

コマンドを作成するクラス Toolが親クラスになっていて子クラスにMagick等が存在する。
MogrifyRestrictedを除いた子クラスは全てこんな感じ

class Magick < MiniMagick::Tool
  def initialize(*args)
    super("magick", *args)
  end
end

superの第一引数が違うだけでそれ以外に差異はない。
MiniMagick::Toolを使うことでImageクラスを使わずにimagemagickのコマンドを直接実行できる。

Shell

Toolで作成したコマンドを実行するクラス。
内部ではコマンドの実行にopen3かposix-spawnが使われている。

デフォルトではopen3が使用され、容量の大きい画像を扱いErrno::ENOMEMの例外を投げられるケースでposix-spawnを使うようドキュメントに書かれている。

Configuration

コンフィグ

Utilities

whichとtempfileの2つのメソッドしかない。
whichのやりたいことはlinuxコマンドのwhichと同じ。

tempfileはImageのインスタンスを作成する際に使われる。
block を渡して任意の処理を実行できる。

def tempfile(extension)
  Tempfile.new(["mini_magick", extension]).tap do |tempfile|
    tempfile.binmode
    yield tempfile if block_given?
    tempfile.close
  end
end

VERSION

バージョン情報

まとめ

ひとまず各クラスの役割をまとめてみた。
標準ライブラリしか使用しておらず、コード量も多くないので初めてOSSのソースを読む人でも理解しやすいと思う。