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 のサムネイルはこんな感じだが、

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.Image を BufferedImage や byte 配列に変換する方法は次回。
こんな感じになる。

格段にキレイだ。
1 Comment
19:09
Spiky
はじめまして。
丁度javaのプログラムでてこずっていて(ほぼ初心者です)、Googleで
検索していてやってきました。
なかなか毎日の日記が実践と苦労から生まれてきているので、
非常にためになります。
一番最新のこの記事ですが、まさに「解決の糸口が。。。」と思い、
読み進めると、「次回に」となっていて、かなりショックを受けました(笑)
実は、あるクラスでImageクラスのimgというインスタンス変数に、
jpegファイルから読み込んだデータが保管されているのですが、
これをJPIを使ってMySQLのデータベースに登録したいのですが、
登録をしようとしているテーブルのフィールドの型を、byte []にして
いるのです。
とりあえずimgは表示しなくて(いや実際表示はすでにできているので)
そのまま(とこう書いている裏には、imgにはjpeg圧縮されたデータが
生のまま入っているのでは?という憶測があるからですが)byte []配列に
渡してデータベースに登録をしたいのです。
このImageクラスのimgのデータをbyte[]へ変換する方法がわからずに
ここ数日数冊のJava本とネットをくびっぴきで探しています。
そもそもImageクラスとか、ImageIOとか、そのような概念を基本的な
ところからきちんと理解していないがために、とんでもない勘違いをしている
可能性もあるのですが、是非この続きを近日中によろしくお願いします。
楽しみにしております。m(v_v)m