JAIを使って画像を縮小する

Java Advanced Imaging(JAI)を使って画像を縮小する方法.
JAIは高機能画像処理ライブラリで,標準のJDKには入っていないので,別途https://jai.dev.java.net/binary-builds.htmlよりjarをダウンロードしてくる.
とりあえず良く分からなかったので,最新版の
jai-1_1_3-lib.zip(Java (no native acceleration))をダウンロード.展開してできた,2つのjarをビルドパスに追加.

んで,サンプルコードは以下のとおり.(sourceFileで指定した画像を1/3に縮小変換するサンプル)


/**
* JAIを使って画像を縮小する
* @param sourceFile 元画像ファイルパス
* @param targetFile 変換先画像ファイルパス
* @throws IOException
*/

public void resizeByJAI(String sourceFile, String targetFile) throws IOException{
// 元画像の読み込み
FileSeekableStream stream = new FileSeekableStream(sourceFile);
RenderedOp image = JAI.create("stream", stream);

// 補間方法の指定
Interpolation interp = Interpolation.getInstance(Interpolation.INTERP_BICUBIC_2);

ParameterBlock params = new ParameterBlock();
params.addSource(image);
params.add(0.33F);//縮小率
params.add(0.33F);//縮小率
params.add(0.0F);
params.add(0.0F);
params.add(interp);

// 画像の縮小
RenderedOp resizedImage = JAI.create("scale", params);

// 変換画像の出力
JAI.create("filestore", resizedImage, targetFile, "png", null);
}

こいつを実行してみたところ,以下のようなエラーが発生するものの,縮小変換後の画像ファイルはちゃんと出力されてる.謎.

(エラーが発生したのは,上記コードの下から4行目のJAI.create("scale", params)の箇所)


Error: Could not find mediaLib accelerator wrapper classes. Continuing in pure Java mode.
Occurs in: com.sun.media.jai.mlib.MediaLibAccessor
java.lang.NoClassDefFoundError: com/sun/medialib/mlib/Image
at com.sun.media.jai.mlib.MediaLibAccessor$1.run(MediaLibAccessor.java:248)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.media.jai.mlib.MediaLibAccessor.setUseMlib(MediaLibAccessor.java:245)
at com.sun.media.jai.mlib.MediaLibAccessor.useMlib(MediaLibAccessor.java:177)
at com.sun.media.jai.mlib.MediaLibAccessor.isMediaLibCompatible(MediaLibAccessor.java:357)
at com.sun.media.jai.mlib.MediaLibAccessor.isMediaLibCompatible(MediaLibAccessor.java:315)
at com.sun.media.jai.mlib.MlibScaleRIF.create(MlibScaleRIF.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
at javax.media.jai.RenderedOp.getSampleModel(RenderedOp.java:2233)
at com.sun.media.jai.codecimpl.PNGCodec.canEncodeImage(PNGCodec.java:54)
at javax.media.jai.operator.FileStoreDescriptor.validateArguments(FileStoreDescriptor.java:176)
at javax.media.jai.JAI.createNS(JAI.java:1086)
at javax.media.jai.JAI.create(JAI.java:973)
at javax.media.jai.JAI.create(JAI.java:1668)
at ImageResizeApp.resizeByJAI(ImageResizeApp.java:76)

エラーメッセージによれば,com.sun.medialib.mlib.Imageってぇのが見つからないらしい.なるほど追加した2つのjar(jai_core.jarとjai_codec.jar)の中にはそれらしきものは入っていない.調べてみたところ,com.sun.medialib.mlib.Imageは,mlibwrapper_jai.jarの中にあるらしい.

しょーがないので,JAIのサイトから,JAIのJDK(jai-1_1_3-lib-windows-i586-jdk.exe)をダウンロードしてインストール.

%JAVA_HOME%/jre/lib/ext/ に展開された中に,mlibwrapper_jai.jarがあったので,こいつをビルドパスに追加して実行してやったところ,めでたくエラーが消えた.

というわけで,縮小は可能になったのだけど,期待していたほど画質が良くない.画質は縮小時の補間方法で決まるのでInterpolation.getInstanceの値をいろいろ変えてみたけど,もっとも画質が良いはずの「Interpolation.INTERP_BICUBIC_2」でもたいしたことない.