グラフィックへ戻る | サンプル集目次へ戻る

実行結果
ImageCopyサンプルソース
画像をスムーズに拡大縮小する方法、java.awt.ImageのgetScaledInstanceメソッドを紹介します。
ImageCopy.java
/**
 * 愛のJava256本ノック for Java 5.0
 * Javaサンプルソース ver0.2C "ImageCopy"
 * ImageCopy.java 「画像をスムーズに拡大縮小」
 *
 * 2005/09/23 制作:安永ノリカズ
 *
 * 【コンパイル&実行方法】
 *     >javac ImageCopy.java
 *     >java ImageCopy
 * 【キーワード】
 *     スケーリング(scaling:拡大縮小), 非同期(asynchronous), 
 * 【試してみよう】
 *     縮小してみる。
 *     SCALE_SMOOTHと他のスケーリングアルゴリズムを比較する。
 */
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.lang.String;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ImageCopy extends JFrame {

    public ImageCopy() {
        add(new DrawPanel());
    }

    public static void main(String[] A00) {
        Toolkit.getDefaultToolkit().setDynamicLayout(true);

        JFrame L00 = new ImageCopy();
        L00.setTitle("イメージを拡大コピー");
        L00.setDefaultCloseOperation(EXIT_ON_CLOSE);
        L00.setSize(400, 400);
        L00.setVisible(true);
    }
}

class DrawPanel extends JPanel {
    static final String C00 = "image/image.gif";
    static final int C01 = 130;        // スケール率(%)
    Image I00;
    int I01;
    int I02;
    Image I03;

    public DrawPanel() {
        setBackground(Color.white);

        I00 = new ImageIcon(C00).getImage();
        I01 = I00.getWidth(this);
        I02 = I00.getHeight(this);

        I03 = I00.getScaledInstance(I01 * C01 / 100, -1, Image.SCALE_SMOOTH);

        MediaTracker L00 = new MediaTracker(this);
        L00.addImage(I03, 1);
        try {
            L00.waitForAll();
        } catch (InterruptedException L01) {
        }
    }

    public void paintComponent(Graphics A00) {
        super.paintComponent(A00);

        A00.drawString("原寸", 10, 20);
        A00.drawImage(I00, 10, 25, this);

        A00.drawString("単純に拡大(" + C01 + "%)", 10, 180);
        A00.drawImage(I00, 10, 185, I01 * C01 / 100, I02 * C01 / 100, this);

        A00.drawString("スムーズに拡大(" + C01 + "%)", 200, 180);
        A00.drawImage(I03, 200, 185, this);
    }
}
/* ■ クラスの外でちょっと一言 ■
画像の拡大表示といえば、java.awt.GraphicsのdrawImageで、幅と高さを指定す
る方法が有名ですが、画質はあまり良くありません。特に元画像がイラストタッ
チの輪郭のくっきりした絵だと、そのアラは目立ちます。Graphics2Dでアンチエ
イリアスを指定しても、図形や線の描画にしか適用されませんので対処不可能。

そこで登場するのがjava.awt.ImageのgetScaledInstanceメソッド。これは、元
の画像を拡大縮小した新たなImageオブジェクトを作ってくれます。その際に
「画質優先」「速度優先」などアルゴリズムを指定することができます。

このサンプルで指定した「SCALE_SMOOTH」はもっとも滑らかな画質で拡大縮小す
るもの。その分、処理は遅くなってます。今回は、コンストラクターで1度生成
するだけですが、paintComponentなどで頻繁に行う可能性がある場合は、画質を
落として処理速度を優先する選択肢も考慮してください。

getScaledInstanceメソッドで、高さに-1を指定してるのは、「width と height
のどちらかが負の数値の場合、元のイメージ寸法の縦横比を維持する(APIドキュ
メントより)」からです。

このメソッドで気をつけなければいけないのは、非同期にイメージをロードする
ということ。つまり、MediaTrackerを使ってロードの終了を待つ必要がありま
す。Javaでは、非同期に画像を読み込むことが多いので、この対処方法を覚えて
おいてください。
 */
↑ 先頭へ戻る

安永ノリカズのゲーム制作&Javaサンプル集 / Java初心者用サンプル集『愛のJava256本ノック』