SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

サーバサイドではじめるJavaグラフィック講座

Javaにおけるイメージのフィルタ処理

サーバサイドではじめるJavaグラフィック講座 4

ルックアップテーブルの操作

 一律に輝度を計算するのではなく、それぞれの値ごとに変更する値を細かに指定したい場合には、「ルックアップテーブル」と呼ばれるものを操作するフィルタ処理を行います。通常、フルカラーのビットマップイメージでは、各ビットのRGB(A)のそれぞれに0~255の値が設定されています。これを「輝度がゼロの場合は○○にする」「輝度が1の場合は××にする」……というように0~255のすべての値ごとに変更する値を指定するテーブルを用意し、これに基づいて輝度の変更を行うわけです。

 これも、実際に簡単な例を挙げましょう。

public BufferedImage getModifiedImage(BufferedImage im) {
    byte[] table = new byte[256];
    for (int i = 0; i < 256; i++) {
        table[i] = (byte)(i < 128 ? 0 : 255);
    }

    int w1 = im.getWidth(), h1 = im.getHeight();
    BufferedImage im2 = new BufferedImage(w1, h1, im.getType());

    ByteLookupTable blt = new ByteLookupTable(0,table);
    LookupOp op = new LookupOp(blt,null);
    op.filter(im, im2);

    return im2;
}
イメージのRGBそれぞれを2階調に変更する
イメージのRGBそれぞれを2階調に変更する

 これは、輝度が128未満ならばゼロに、それ以上なら255に変更するものです。つまり、RGBのそれぞれで輝度を強制的に2階調にしてしまうわけです。いかにもフィルタ処理した、という感じになってきましたね?

 ここで使用しているのは、「LookupOp」というクラスです。これは、あらかじめ用意してあるルックアップテーブルのクラス「LookupTable」のインスタンスと、RenderingHintsインスタンスを引数に指定して作成をします。

new LookupOp( LookupTable table, RenderingHints hint)

 このような形です。RescaleOpと同様、RenderingHintsは不要ならnullでかまいません。そして、filterメソッドを呼び出すことで、第1引数のイメージをフィルタ処理し、第2引数のBufferedImageに描画します。

 このLookupOpのポイントは、引数に指定するLookupTableをどのように作成するか、でしょう。LookupTableクラスは抽象クラスとして定義されているので、通常はこれを継承したByteLookupTableShortLookupTableを利用するのが一般的です。

 ここではByteLookupTableを使っています。これは、第1引数にオフセット値を、第2引数に各輝度の値をどのような値に変更するかをbyte配列としてまとめたものを指定します。ここでは、配列の値を次のようにして用意していますね。

byte[] table = new byte[256];
for (int i = 0; i < 256; i++) {
    table[i] = (byte)(i < 128 ? 0 : 255);
}

 128未満であればゼロを、それ以上ならば255を指定しています。これですべての輝度をゼロか255に変更するテーブルが作成できたわけです。同様の考え方で、4階調、8階調などに変更することも行えるでしょう。

 また、先のRescaleOpと同様に、複数のテーブル用配列を用意することで、RGB(A)のそれぞれにテーブルを指定して変換することも可能です。

public BufferedImage getModifiedImage(BufferedImage im) {
    byte[] tableR = new byte[256];
    byte[] tableG = new byte[256];
    byte[] tableB = new byte[256];
    for (int i = 0; i < 256; i++) {
        tableR[i] = (byte)(i < 128 ? 0 : 255);
        tableG[i] = (byte)i;
        tableB[i] = (byte)(256 -i);
    }

    int w1 = im.getWidth(), h1 = im.getHeight();
    BufferedImage im2 = new BufferedImage(w1, h1, im.getType());

    ByteLookupTable blt =
        new ByteLookupTable(0,new byte[][]{tableR,tableG,tableB});
    LookupOp op = new LookupOp(blt,null);
    op.filter(im, im2);

    return im2;
}
イメージの赤を2階調に、青を反転させる
イメージの赤を2階調に、青を反転させる

 ここでは、赤を2階調にし、緑をそのまま、青の階調を逆転させるというフィルタ処理をさせてみました。ここでは、あらかじめ3つのbyte配列を用意しておき、ByteLookupTableの引数に、new byte[][]{tableR,tableG,tableB}として各配列を一つの配列にまとめたものを渡しています。

次のページ
ぼかし処理について

この記事は参考になりましたか?

サーバサイドではじめるJavaグラフィック講座連載記事一覧

もっと読む

この記事の著者

掌田 津耶乃(ショウダ ツヤノ)

三文ライター&三流プログラマ。主にビギナーに向けたプログラミング関連の執筆を中心に活動している。※現在、入門ドキュメントサイト「libro」、カード型学習サイト「CARD.tuyano.com」を公開...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1145 2007/04/06 08:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー