はじめに
Javaの標準機能だけで画像処理をする場合、BufferedImageクラスを用いることになります。
そもそもJava自体が画像処理向きの言語ではありませんし、OpenCVなどの外部ライブラリを使うのが一般的だと認識しています。
ただし、外部ライブラリを入れなくても画像処理ができるというメリットはあり、何らかの理由で使うこともあるかもしれませんので、備忘もかねてBufferedImageの基本的な使い方を記しておこうと思います。
画像の生成
コンストラクタを呼び出すだけで真っ新な画像が生成されます。
実際に動かす際にはwidth(幅)やheight(高さ), type(タイプ)に任意の値を入れてください。
typeは事前定義されているのでそれを指定することになります。
通常のRGBカラー画像であればTYPE_INT_RGBを、AlphaチャネルありのARGB画像であればTYPE_INT_ARGBを指定すればOKです。
var bi = new BufferedImage(width, height, type);
画像の読み込み
ImageIOクラスを用いることで、ファイル指定で読み込みができます。
例外処理は適当なので適宜変更してください。
public static BufferedImage read(String filename) {
try {
return ImageIO.read(new File(filename));
} catch (IOException e) {
e.printStackTrace();
}
return new BufferedImage(0, 0, 0);
}
画像の書き出し
読み込みと同じようにImageIOクラスを用いて実装できます。
引数として拡張子が必要なので、下記の例ではsubstringメソッドを利用して拡張子を抽出しています。
public static void write(BufferedImage bi, String filename) {
try {
String extension = filename.substring(filename.lastIndexOf(".") + 1);
ImageIO.write(bi, extension, new File(filename));
} catch (IOException e) {
e.printStackTrace();
}
}
パラメータの取得
画像の幅、高さ、タイプは対応するgetメソッドで取得できます。
下記のbiはBufferedImageのインスタンスです。
int width = bi.getWidth();
int height = bi.getHeight();
int type = bi.getType();
画素値の取得
インデックス(x,y)の画素値をカラーごとにint配列で取得します。
ビットシフトをしてからビットマスクをすることで、8bit(0~255)を切り出すという仕組みです。
先頭からAlpha, Red, Green, Blueの順に画素は並んでいるので、8bitずつずらしていくことで各カラーの値を取得できます。
public static int[] getRGB(BufferedImage bi, int x, int y) {
int pixel = bi.getRGB(x, y);
int red = pixel >> 16 & 0xff;
int green = pixel >> 8 & 0xff;
int blue = pixel & 0xff;
return new int[]{red, green, blue};
}
public static int[] getARGB(BufferedImage bi, int x, int y) {
int pixel = bi.getRGB(x, y);
int alpha = pixel >>> 24;
int red = pixel >> 16 & 0xff;
int green = pixel >> 8 & 0xff;
int blue = pixel & 0xff;
return new int[]{alpha, red, green, blue};
}
画素値の設定
インデックス(x,y)に画素値を設定します。
取得時と逆の操作でビット演算することにより32bitのARGBカラーで値を設定できます。
public static void setRGB(BufferedImage bi, int x, int y, int[] rgb) {
int pixel = 0xff000000 | rgb[0] << 16 | rgb[1] << 8 | rgb[2];
bi.setRGB(x, y, pixel);
}
public static void setARGB(BufferedImage bi, int x, int y, int[] argb) {
int pixel = argb[0] << 24 | argb[1] << 16 | argb[2] << 8 | argb[3];
bi.setRGB(x, y, pixel);
}
画像の表示
これはおまけですが、SwingのJFrameも組み合わせることで、簡単に画像を表示することもできます。
下記はあくまでもサンプルですが、コンストラクタでウィンドウの設定を変更することも可能です。
/**
* 画像を表示する
*
* @param bi BufferedImage型の画像
*/
public static void show(BufferedImage bi) {
new Viewer(bi);
}
/**
* 画像表示用のフレーム
*/
private static class Viewer extends JFrame {
/**
* 表示する画像
*/
BufferedImage bi;
/**
* コンストラクタ
*
* @param bi BufferedImage型の画像
*/
public Viewer(BufferedImage bi) {
this.bi = bi;
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(bi.getWidth(), bi.getHeight());
setVisible(true);
setResizable(false);
}
@Override
public void paint(Graphics g) {
g.drawImage(bi, 0, 0, null);
}
}