Javaエンジニア・プログラマ向けの技術情報・業界ニュースをお届けします。

  1. FEnetJava
  2. Javaコラム
  3. Java入門
  4. Javaの画像処理を基礎から解説!

Javaの画像処理を基礎から解説!

  • Java入門
公開日時:   更新日時:
Javaの画像処理を基礎から解説!
この記事でわかること
    システム
    エンジニア
    Javaの画像処理とはどのような処理のことでしょうか。
    プロジェクト
    マネージャー
    Javaでグラフィックを描画すること全てが該当します。

    Javaの画像処理とは?


    Javaの画像処理と言えば、Javaでグラフィックを描画すること全てが該当します。今回は画像ファイルを読み込んで何かの処理を行って保存する、という一連の動作を画像処理として扱いましょう。

    Javaの画像処理はImageIOクラスを利用します。そして読み込んだ画像はBufferedImageクラスのデータとして扱います。まずはとても簡単な、画像ファイルを読み込んで保存するだけの処理を行ってみましょう。

    画像ファイルを読み込んで保存するサンプル

    以下はpng形式の画像ファイルを開いて、jpg形式で保存するJavaサンプルです。実行して試してみてください。

    import java.io.*;
    import java.awt.image.*;
    import javax.imageio.*;

    public class MainClass {
    public static void main(String[] args) {
    try {
    BufferedImage bi = ImageIO.read(new File(“”c:\\test\\test.png””));
    ImageIO.write(bi, “”jpg””, new File(“”c:\\test\\test.jpg””));
    }
    catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    画像処理のサンプル

    次はもう少し凝った画像処理をしてみましょう。以下のJavaサンプルをご覧ください。

    import java.io.*;
    import java.awt.image.*;
    import javax.imageio.*;

    public class MainClass {
    public static void main(String[] args) {
    try {
    BufferedImage readBuf=ImageIO.read(new File(“”c:\\test\\test.jpg””));
    int w = readBuf.getWidth();
    int h = readBuf.getHeight();
    BufferedImage writeBuf =
    new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

    for(int y=0;y < h;y++){
    for(int x=0;x < w;x++){
    int c = readBuf.getRGB(x, y);
    c &= 0xff0000ff;
    writeBuf.setRGB(x,y,c);
    }
    }

    ImageIO.write(writeBuf, “”jpg””, new File(“”c:\\test\\test2.jpg””));
    }
    catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    画像処理の基礎

    このサンプルを実行すると、test.jpgを画像処理してtest2.jpgに保存します。test2.jpgはtest.jpgを真っ青にしたような画像になっているはずです。これはtest.jpgから青の要素だけ取り出してtest2.jpgに保存したからです。

    Javaサンプルのプログラムについて解説する前に、まず画像処理の基礎を簡単に説明します。画像ファイルはピクセル(ドット)の集まりで出来ています。画像ファイルを画像ビューワで拡大すると、画像が縦横のマス目で構成されていることがわかります。そのマス目がピクセルです。

    ピクセルにはRGBの値が入っている

    色というものは赤・緑・青の三原色から成り立ちます。コンピューターではそれをRGB(Red・Green・Blue)とセットで表します。そして画像ファイルの各ピクセルにはRGBの値が入っているのです。例えばRGBのRが最高値でGとBが0なら、ピクセルは真っ赤になるということです。

    つまり画像ファイルはRGB値のピクセルの集合体ということです。それを踏まえた上で、Javaの画像処理サンプルの解説に入ります。

    TYPE_INT_RGBで書き込み用バッファを生成する

    今回のJavaの画像処理サンプルではまずBufferedImageに画像を読み込んだ後、getWidth()とgetHeight()でサイズを取得しています。これが横と縦のピクセル数ということです。そしてその縦横サイズで書き込み用のwriteBufを作成しています。

    その時にTYPE_INT_RGBを指定していますが、これはRGBそれぞれが8ビットの値を持つピクセルのBufferedImageを作成するという意味です。8ビットとは、10進数で0から255、16進数で0x00~0xffの値を持つサイズの単位です。

    1つのピクセルは3つの8ビットの値から構成されている

    サンプルソースの、「int c = readBuf.getRGB(x, y);」の次に以下を追加して実行してみてください。

    if (y==h/2 && x==w/2) System.out.println(Integer.toHexString(c));

    これは画像の中心辺りの場所のピクセルの値を表示します。画像ファイルの内容にもよりますが、以下のように表示されるはずです。

    ff927f3d

    これは16進数で、

    未使用 = 0xff
    R = 0x92
    G = 0x7f
    B = 0x3d

    と言う意味です。このように1つのピクセルは8ビットサイズの3つのRGB値から構成されているのです。なお未使用の部分にはARGBの場合はAlpha値という透明度が入ります。

    ピクセルの値にビット演算を行う

    Javaの画像処理サンプルの解説に戻りましょう。writeBufを生成した後は、画像ファイルのサイズの分だけ、2重のforループ処理を行って各ピクセルの読み込みと書き込み処理を行います。readBuf.getRGB(x, y)で変数cにピクセルのRGB値を読み込んで、

    c &= 0xff0000ff;

    と言う処理を行っています。これはビット演算です。先ほどのケースで1つのピクセルは8桁の16進数で表せると分かりましたが、このビット演算で未使用値とBlueだけを残して、RedとGreenは00にしてしまいます。

    ビット演算でBだけを残す

    ビット演算の箇所は、以下のようにJavaの2進数表記で置き換えることもできます。

    c &= 0b1111_1111_0000_0000_0000_0000_1111_1111;

    0と1だけの2進数の場合は32桁になりますが、&=の場合その各桁で乗算を行います。その結果、0の桁が消えて1の桁が残ります。ビット演算についてはここではこれ以上詳しくは説明しないので、他を調べてみてください。

    画像を明るくするサンプル

    変数cにビット演算を行った後は、setRGB(x,y,c)でwriteBufに書き込みます。これを全ピクセル行います。最後にImageIO.writeでwriteBufをファイルに書き込んで終了です。このようにビット演算さえ理解すればJavaの画像処理はそれほど難しくはありません。

    では次に青だけを残しているc &= 0xff0000ff;の箇所を、以下のように変えてみましょう。

    int r = (c & 0x00ff0000) >> 16;
    int g = (c & 0x0000ff00) >> 8;
    int b = c & 0x000000ff;
    final int add = 0x40;
    r += add;
    if (r > 0xff) r = 0xff;
    g += add;
    if (g > 0xff) g = 0xff;
    b += add;
    if (b > 0xff) b = 0xff;
    c = 0xff000000 | (r << 16) | (g << 8) | b;

    画像処理のプログラムにはビット演算の知識は必須

    これを実行するとtest2.jpgはtest.jpgより明るくなります。RGBそれぞれに0x40を加算して色を底上げしているというわけです。RGBは全てが0xffになると白になるので、白っぽくなったとも言えます。

    行っていることは、まずRを&で取得して右に16ビットシフト、Gを&で取得して右に8ビットシフト、Bを&で取得します。それぞれに0x40を加算、ただし0xffは越えないようにします。そして未使用の0xff000000・Rを左16ビットシフト・Gを左8シフト・Bを、それぞれ|(OR)で加算して新しいピクセルの値とする、です。

    ビット演算が分からない人は、ビット演算のやり方を調べてからもう一度見直してください。理解できるようになるでしょう。

    システム
    エンジニア
    Javaの画像処理は難しいイメージでしたが、やり方さえ分かれば簡単にできるのですね。
    プロジェクト
    マネージャー
    ビット演算さえ理解できれば、初心者でも難しくない作業です。

    Javaの画像処理は難しくない!

    Javaの画像処理について解説しましたが、ご理解頂けましたでしょうか。ビット演算の知識が必要になりますが、それをマスターすれば後は自在に画像処理ができるようになるでしょう。

    FEnetJava・Javaコラムは株式会社オープンアップシステムが運営しています。
    株式会社オープンアップシステムロゴ

    株式会社オープンアップシステムはこんな会社です

    秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
    数多くのエンジニアが集まります。

    秋葉原オフィスイメージ
    • スマホアプリから業務系システムまで

      スマホアプリから業務系システムまで

      スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。

    • 充実した研修制度

      充実した研修制度

      毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。

    • 資格取得を応援

      資格取得を応援

      スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。

    • 東証プライム上場企業グループ

      東証プライム上場企業グループ

      オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。

      安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。

    株式会社オープンアップシステムに興味を持った方へ

    株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。

    年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
    まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。

    株式会社オープンアップシステムへのご応募はこちら↓
    株式会社オープンアップシステムへのご応募はこちら↓

    Java新着案件New Job