Java入門|画像の読み込みと表示

画像表示の第一歩。ウィンドウの中に絵を呼び出して、Javaの画面をもっと表情豊かにしよう。

これまでのGUIアプリケーションでは、ウィンドウを表示したり、ボタンやラベルを置いたり、イベントに反応させたりしてきました。
ここまででも、すでにアプリケーションらしい形はできていますが、画面の中に画像が表示されるようになると、ぐっと表現の幅が広がります。

ドラゴンボールの世界でたとえるなら、これまでは修行部屋に文字の案内板や操作ボタンだけが置かれていた状態でした。けれど、そこに悟空の修行マークや、特訓メニューのイラスト、ドラゴンレーダー風の図が表示されるようになると、一気に画面がにぎやかになり、何を表しているのかも直感的に分かりやすくなります。

Javaでは、画像ファイルを読み込んで、ウィンドウの中に描画することができます。
そのときに大切になるのが、画像を読み込む仕組みと、画面に描くための paint() メソッド、そして Graphics クラスです。

ここでは、画像を読み込んで表示する基本の流れを、ドラゴンボールの世界観に置きかえながら、やさしくていねいに見ていきます。

画像を表示するとはどういうことか

GUIアプリケーションで画像を表示するというのは、ただファイルを開くだけではありません。
Javaのプログラムの中で画像ファイルを読み込み、その画像をウィンドウの中の指定した場所に描画する、という流れになります。

この流れを簡単に整理すると、次のようになります。

手順内容
1画像ファイルを用意する
2プログラムから画像を読み込む
3paint() メソッドの中で描画する
4ウィンドウに画像が表示される

ドラゴンボール風にいえば、修行部屋の壁に飾る修行ポスターを、倉庫から取り出して、壁の決まった位置に貼るような流れです。
画像ファイルを持ってくるだけではまだ足りず、画面のどこにどう見せるかを描画の処理として書く必要があります。

サンプルプログラム:画像描画の例

この例では、同じフォルダの中に training.jpg という画像ファイルを置いて、その画像をウィンドウ内に表示します。

ファイル名:Sample5.java

import java.awt.*;
import java.awt.event.*;

public class Sample5 extends Frame
{
    Image im;

    public static void main(String[] args)
    {
        Sample5 sm = new Sample5();
    }

    public Sample5()
    {
        super("修行カード表示");

        // ツールキットを取得する
        Toolkit tk = getToolkit();

        // 画像ファイルを読み込む
        im = tk.getImage("training.jpg");

        addWindowListener(new SampleWindowListener());

        setSize(420, 320);
        setVisible(true);
    }

    public void paint(Graphics g)
    {
        // 画像をウィンドウに描画する
        g.drawImage(im, 115, 80, this);

        // 補足の文字も描画する
        g.drawString("きょうの修行イメージ", 160, 60);
    }

    class SampleWindowListener extends WindowAdapter
    {
        public void windowClosing(WindowEvent e)
        {
            System.exit(0);
        }
    }
}

ファイル名:training.jpg

このプログラムでできること

このプログラムを実行すると、「修行カード表示」というタイトルのウィンドウが開きます。
その中には、training.jpg という画像ファイルが表示され、さらにその上に「きょうの修行イメージ」という文字も描画されます。

このプログラムで行っていることを整理すると、次のようになります。

できること内容
ウィンドウを表示するFrame を使って画面を作る
画像を読み込むToolkit と getImage() を使う
画像を描画するpaint() の中で drawImage() を使う
文字も描画するdrawString() を使う
閉じる操作に対応するWindowAdapter を使う

つまり、このサンプルでは単に画像を表示するだけでなく、描画の仕組みそのものにも触れています。

まずは画像ファイルを用意する

画像を表示するには、当然ですが元になる画像ファイルが必要です。
今回の例では、training.jpg というファイルを使っています。

im = tk.getImage("training.jpg");

このファイル名は、Javaのコードと同じフォルダに置かれている画像を読み込む、という意味で使っています。
そのため、プログラムを実行するときは、Sample5.java と training.jpg を同じ場所に置いておく必要があります。

ドラゴンボール風にいうと、修行カードを壁に表示したいなら、まずそのカードの絵そのものを用意して、修行室の倉庫に置いておく必要があるわけです。

Toolkit とは何か

画像を読み込む前に、次のような記述があります。

Toolkit tk = getToolkit();

Toolkit は、AWTで画面表示や画像処理などを扱うための基本的な道具箱のような存在です。
この Toolkit を通して、画像の読み込みなどを行います。

初心者の段階では、Toolkit を細かく難しく考えすぎなくても大丈夫です。
まずは、AWTの画像や画面まわりの機能を使うための窓口くらいに捉えると分かりやすいです。

ドラゴンボール風にいえば、Toolkit は修行装置を操作するための共通コントロール盤のようなものです。
そこを通じて、画像という素材を取り出してきます。

getImage() で画像を読み込む

実際に画像を読み込んでいるのがこの部分です。

im = tk.getImage("training.jpg");

ここでは、Toolkit の getImage() メソッドを呼び出して、training.jpg という画像ファイルを Image 型の変数 im に読み込んでいます。

ここで大事なのは、画像を読み込む処理と、画面に表示する処理は別だということです。
getImage() はあくまで画像を取り出して準備しているだけで、この時点ではまだウィンドウに表示されていません。

この流れを整理すると、こうなります。

処理役割
getToolkit()画像を扱うための道具を取得する
getImage("training.jpg")画像ファイルを読み込む
im に代入画像データを保持しておく

つまり、ここでは「表示するための材料を準備している」段階です。

paint() メソッドの役割

画像を実際に画面へ表示するために使うのが paint() メソッドです。

public void paint(Graphics g)
{
    g.drawImage(im, 115, 80, this);
    g.drawString("きょうの修行イメージ", 160, 60);
}

paint() は、ウィンドウが描画されるときに呼び出される特別なメソッドです。
JavaのGUIでは、画面に何かを描きたいときに、この paint() の中で処理を書くことが多いです。

ドラゴンボール風にいえば、paint() は修行室の壁に「今から何を表示するか」を実際に描き込むタイミングです。
画像や文字などを、ここでまとめて描いていきます。

drawImage() で画像を描画する

画像を描画している中心のコードはこれです。

g.drawImage(im, 115, 80, this);

このコードの意味を分けると、次のようになります。

部分意味
im描画する画像
115横方向の位置
80縦方向の位置
this画像の描画を監視する対象

初心者のうちは、まず 指定した画像を、指定した座標に表示する という理解で十分です。

今回なら、training.jpg をウィンドウの左上から右下にずらした位置に表示しています。
もし数字を変えれば、画像の表示位置も変わります。

たとえば、

g.drawImage(im, 20, 50, this);

とすれば、もっと左寄りで少し上の位置に表示されます。

drawString() で文字を描く

今回のサンプルでは、画像だけでなく文字も描いています。

g.drawString("きょうの修行イメージ", 160, 60);

これは paint() の中で文字列を描画する命令です。
つまり Graphics を使うと、画像だけでなく文字も同じように画面に描けます。

ここでは画像の上に説明タイトルを置くために使っています。
ドラゴンボール風にいえば、修行カードの上に「本日の特訓内容」といった見出し札を描いている感じです。

Graphics クラスとは何か

paint() の引数にある Graphics g は、画面に何かを描くための道具です。
この Graphics を使って、画像、文字、線、四角形、円などを描けます。

つまり Graphics は、ウィンドウの中に絵を描くためのペンや筆のような役割を持っています。

ドラゴンボールでたとえるなら、Graphics は修行ボードに図や文字を書き込むための万能マーカーのようなものです。
どんな線を引くか、どんな文字を書くか、どこに絵を置くかを決めるのが Graphics です。

Graphics クラスの主なメソッド

Graphics にはいろいろな描画用メソッドがあります。
よく使うものを整理すると、次のようになります。

メソッド名機能
drawImage(Image img, int x, int y, ImageObserver observer)画像を描く
drawLine(int x1, int y1, int x2, int y2)線を描く
drawRect(int x, int y, int width, int height)四角形を描く
drawOval(int x, int y, int width, int height)楕円を描く
drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)円弧を描く
drawPolygon(int[] xPoints, int[] yPoints, int nPoints)多角形を描く
drawString(String str, int x, int y)文字列を描く
fillOval(int x, int y, int width, int height)塗りつぶした楕円を描く
fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)塗りつぶした円弧を描く
fillPolygon(int[] xPoints, int[] yPoints, int nPoints)塗りつぶした多角形を描く
setColor(Color c)色を設定する
setFont(Font font)フォントを設定する

Graphics のメソッドをドラゴンボール風に見る

描画メソッドの役割をドラゴンボール風のイメージにすると、こんなふうに考えられます。

メソッドドラゴンボール風のイメージ
drawImage()修行カードやキャラクター画像を表示する
drawLine()修行ルートやエネルギーの流れを線で示す
drawRect()情報パネルやメニュー枠を描く
drawOval()気の玉やレーダーの輪を描く
drawString()修行名や説明文を表示する
setColor()案内の色や警告色を切り替える
setFont()タイトルや説明文の見た目を変える

こうして見ると、画像表示だけでなく、Graphics を使えばかなりいろいろな画面表現ができることが分かります。

画像表示の流れを整理する

画像表示の基本は、次の順番で理解するとすっきりします。

1. 画像を入れる変数を用意する

Image im;

まず、Image 型の変数を用意しておきます。

2. Toolkit を取得する

Toolkit tk = getToolkit();

画像を扱うための道具を取得します。

3. getImage() で画像を読み込む

im = tk.getImage("training.jpg");

画像ファイルを読み込みます。

4. paint() をオーバーライドする

public void paint(Graphics g)

ウィンドウに描画するときの処理を書く場所です。

5. drawImage() で画像を描画する

g.drawImage(im, 80, 80, this);

指定した位置に画像を表示します。

この順番が分かると、画像表示の仕組みがかなり見えやすくなります。

なぜ paint() の中で描くのか

初心者のときに少し不思議に感じやすいのが、「なぜコンストラクタの中ではなく paint() の中で描くのか」という点です。

理由は、paint() が 画面の描画タイミングで呼ばれるメソッド だからです。
ウィンドウが表示されたとき、再描画が必要になったときなどに paint() が呼ばれます。

つまり、JavaのGUIでは「画面に見えるものは paint() の中で描く」という考え方が基本になります。

ドラゴンボール風にいえば、修行部屋の表示パネルは、電源が入ったときや表示更新のタイミングで、自動的に再描画されます。その描き直しの場が paint() です。

この図が示していること

この図では、画像ファイルが Toolkit を通して読み込まれ、Image 型の変数に入れられ、最後に paint() の中で drawImage() によってウィンドウへ描画される流れを示します。
つまり、画像表示は「画像を用意する」「読み込む」「描く」という3段階で成り立っていることが分かります。
また、paint() が画面描画の中心であり、Graphics が実際の描画を担当していることも分かります。

画像表示で気をつけたいこと

画像を扱うときは、いくつか気をつけたい点があります。

画像ファイルの場所

Javaファイルと画像ファイルの位置がずれていると、読み込みに失敗しやすいです。
学習段階では、まず同じフォルダに置く形が分かりやすいです。

ファイル名の書き間違い

training.jpg と書くべきところを Training.jpg や training.jpeg と書くと、正しく読み込めないことがあります。
文字の違いもきちんと合わせることが大切です。

paint() の役割を意識する

画像はコンストラクタで直接表示されるのではなく、paint() の中で描かれます。
ここを混同しないことが大切です。

文字・図形・画像を組み合わせる楽しさ

今回のテーマは画像表示ですが、Graphics を使うと、画像だけでなく文字や図形も一緒に描けます。
つまり、ウィンドウの中に

  • 画像
  • タイトル文字
  • 枠線
  • 図形
  • 説明文

を組み合わせて、自分なりの画面を作れるようになります。

これはドラゴンボールの修行画面でいえば、

  • 修行カードの画像を出す
  • 上にタイトルを書く
  • 周りに枠を付ける
  • 必要な説明を下に表示する

といった、画面作りの自由度につながります。

はじめて画像表示を学ぶときの見方

最初は、画像表示のコードが少し特別に見えるかもしれません。
でも、次の流れで見ると整理しやすいです。

何を読み込んでいるのか

Image 型の変数に画像を入れています。

どこで読み込んでいるのか

コンストラクタの中で Toolkit と getImage() を使っています。

どこで表示しているのか

paint() の中で drawImage() を使っています。

何を描画の道具にしているのか

Graphics が描画の役割を持っています。

このように役割で見ていくと、コード全体がかなり分かりやすくなります。

この内容でつかんでおきたいこと

今回のテーマでいちばん大切なのは、画像表示は読み込みと描画に分かれているということです。
画像ファイルを持ってくるだけでは画面には出ず、paint() の中で drawImage() を使ってはじめて表示されます。

押さえておきたいポイントを整理すると、次の通りです。

ポイント内容
Toolkit画像などを扱うための道具を取得する
getImage()画像ファイルを読み込む
Image読み込んだ画像を保持する型
paint()画面描画のタイミングで呼ばれるメソッド
Graphics画像や文字や図形を描くための道具
drawImage()画像を画面に描画する
drawString()文字列を画面に描画する

この流れが見えてくると、JavaのGUIは文字や部品だけでなく、画像も使って表現できることが分かってきます。
画面の中に絵を表示できるようになると、アプリケーションはさらに豊かで分かりやすいものになっていきます。