Corredor

ウェブ、プログラミングの勉強メモ。

「im4java」を使って Java から ImageMagick を呼び出して画像変換や画像情報取得をする

前回紹介した、コマンドラインから画像の変換処理などができる ImageMagick。今回はこの ImageMagick を Java プログラムから呼び出す時に使える、im4java というライブラリを紹介する。

im4java は、ImageMagick のコマンドファイル (convert.exeidentify.exe など) を呼び出すためのラッパーである。つまり im4java 単体では動作せず、利用する環境には ImageMagick をインストールしておく必要がある

im4java のダウンロードと環境構築

im4java は以下からダウンロードできる。最新版は Ver.1.4.0 で、ImageMagick 7系にも対応しているが、Convert コマンドに関しては magick.exe だけでなく convert.exe もインストールしておかないと恐らく動かない。

ダウンロードしたアーカイブを解凍すると、im4java-1.4.0.jar というファイルが入っているので、これを Java プロジェクトのビルドパスに通す。他に依存するライブラリがなく、JAR ファイル1つで完結するのはありがたい。

im4java の使い方

im4java は ImageMagick のコマンドライン・オプションがほとんどそのままの形で記述できるので、変換内容に関しては記述しやすいと思う。が、入力ファイルや出力ファイルの指定方法が少々分かりづらかったので、色々と調べながら組み上げた。

以下に ConvertIdentify のコマンドを im4java から呼び出すサンプルを用意した。それぞれのコマンドで、ファイルのフルパスを文字列で指定する方法と、BufferedImage オブジェクトとして画像を受け渡しする方法を作成した。

ほとんどコード中にコメントで記述したが、注意したいところを以下にまとめておく。

  • im4java が ImageMagick を利用できるように、ImageMagick のインストール先ディレクトリを指定する必要がある。
// ImageMagick のパスを指定する方法は2通り

// コマンドクラスに直接指定する方法
ConvertCmd convert = new ConvertCmd();
convert.setSearchPath("C:/Program Files/ImageMagick-7.0.5-Q16");

// 事前に im4java が全体で使えるように指定する方法
ProcessStarter.setGlobalSearchPath("C:/Program Files/ImageMagick-7.0.5-Q16");

どちらで書いても特に変わらない。

  • 引数を指定する IMOperation#addImage() は、入力ファイルや出力先のフルパスを文字列で指定する。
  • 入力ファイルを BufferedImage オブジェクトにしたい場合は、プレースホルダとして引数なしの IMOperation#addImage() を記述しておき、BufferedImage オブジェクトは ConvertCmd#run()IdentifyCmd#run() の第2引数に指定する。
  • ConvertCmd の結果である変換後のファイルを BufferedImage で受け取る場合は、Stream2BufferedImage というヘルパークラスを利用する。このクラスを ConvertCmd#setOutputConsumer() で結果情報の出力先にセットしておくことで、BufferedImage オブジェクトとして出力することができる (Stream2BufferedImage#getImage())。
  • IdentifyCmd の場合は、標準出力に出力される文字列を受け取るために ArrayListOutputConsumer というヘルパークラスを利用する。ArrayListOutputConsumer#getOutput() で、標準出力の結果1行を1要素とした ArrayList<String> を返却してくれる。
  • サンプルでは Format 指定により、Identify の結果は1行しかないので、StringUtils#join() や、Java8 以降で使える String#join() で結果の List を1つの String にまとめてしまっている。

ImageMagick とこの im4java ライブラリを使えば、ウェブアプリからアップロードされた画像をサーバサイドで変換し、圧縮版をレスポンスで返す、といったことが可能になる。

im4java の動きがよく分からない場合は、公式の API Docs と、StackOverflow での既出の質問が参考になる。