Java ImageIO で Flickr 並みのサムネイル画像をつくる

スポンサード リンク

まあ、記事のタイトルがアレですけど...

Java の Image I/O で画像の縮小を行う方法として、AffineTransformOp を利用する方法がある。

final double scale = 0.5;
AffineTransformOp transformOp = new AffineTransformOp(AffineTransform.getScaleInstance(scale, scale), null);
BufferedImage dest1 = new BufferedImage(
    (int)(originalImage.getWidth() * scale),
    (int)(originalImage.getHeight() * scale),
    originalImage.getType());
transformOp.filter(originalImage, dest1);

しかし、この方法だとジャギーが目立ってしまい、Flickr ほどキレイなサムネイルにはならない。

たとえば、Flickr で見つけたこの写真。Flickr のサムネイルはこんな感じだが、

Bark with Monument Under Rennovation

AffineTransformOp を用いた方法だと、こうなってしまう。

Java ImageIO AffineTransformOp

で、どうするかというと、AWT の AreaAveragingScaleFilter を使うのがいいようだ。以下、API リファレンスより抜粋:

最近接点アルゴリズムよりもなめらかな結果が得られる、簡単な領域平均化アルゴリズムを使用してイメージをスケーリングする ImageFilter クラスです。

では、試してみる。

ImageFilter filter = new AreaAveragingScaleFilter(w, h);
ImageProducer im = new FilteredImageSource(image.getSource(), filter);
Image newImage = Toolkit.getDefaultToolkit().createImage(im);

フィルタした結果の java.awt.ImageBufferedImagebyte 配列に変換する方法は次回。

こんな感じになる。

Java ImageIO AreaAveragingScaleFilter

格段にキレイだ。

コメントを投稿する

1 Comment

Spiky

はじめまして。

丁度javaのプログラムでてこずっていて(ほぼ初心者です)、Googleで
検索していてやってきました。

なかなか毎日の日記が実践と苦労から生まれてきているので、
非常にためになります。

一番最新のこの記事ですが、まさに「解決の糸口が。。。」と思い、
読み進めると、「次回に」となっていて、かなりショックを受けました(笑)

実は、あるクラスでImageクラスのimgというインスタンス変数に、
jpegファイルから読み込んだデータが保管されているのですが、
これをJPIを使ってMySQLのデータベースに登録したいのですが、
登録をしようとしているテーブルのフィールドの型を、byte []にして
いるのです。

とりあえずimgは表示しなくて(いや実際表示はすでにできているので)
そのまま(とこう書いている裏には、imgにはjpeg圧縮されたデータが
生のまま入っているのでは?という憶測があるからですが)byte []配列に
渡してデータベースに登録をしたいのです。

このImageクラスのimgのデータをbyte[]へ変換する方法がわからずに
ここ数日数冊のJava本とネットをくびっぴきで探しています。

そもそもImageクラスとか、ImageIOとか、そのような概念を基本的な
ところからきちんと理解していないがために、とんでもない勘違いをしている
可能性もあるのですが、是非この続きを近日中によろしくお願いします。

楽しみにしております。m(v_v)m

Want fries with that?

Open Source Projects