Javaプログラミング学習サイト ゆるゆるプログラミング

2020/10/19 公開

・指定色の画素数取得

ここでは、画像を読み込み、その画像を構成するピクセル画素)のうち、RGBで指定した色がいくつあるかを数える方法を紹介しています。

コマンドパラメーターで画像ファイル名とRGBの値(0から255)を指定し、その画像の全てのピクセルの色と指定したRGBの値が完全一致しているかを判定し、一致した数をカウントしていきます。

以下が、そのJavaソースコードです。

NumberOfPixels.java ← クリックしてダウンロードページに移動
001:    import java.awt.image.BufferedImage;
002:    import java.io.File;
003:    import javax.imageio.ImageIO;
004:    import java.io.IOException;
005:    
006:    public class NumberOfPixels {
007:    	public static void main( String[] args ) {
008:    		// 画像サイズ
009:    		int width, height;
010:    		// カウントする色
011:    		int rn, gn, bn;
012:    		// ファイル名
013:    		String inname;
014:    		// 画像格納クラス
015:    		BufferedImage img = null;
016:    
017:    		// 入力した引数が4つ以上かを調べる
018:    		if ( 4 > args.length ) {
019:    			// 入力した引数が4つ未満の場合、使用方法を表示する
020:    			System.out.println( "NumberOfPixels [入力画像名] [R] [G] [B]" );
021:    			return;
022:    		}
023:    
024:    		// 入力画像名をinnameに代入(拡張子省略なし)
025:    		inname  = args[ 0 ];
026:    
027:    		// 指定色を代入
028:    		try {
029:    			rn = Integer.valueOf( args[ 1 ] );
030:    			gn = Integer.valueOf( args[ 2 ] );
031:    			bn = Integer.valueOf( args[ 3 ] );
032:    		}
033:    		catch( NumberFormatException ne )
034:    		{
035:    			System.out.println( "引数が不正です" );
036:    			return;
037:    		}
038:    
039:    		// 画像の読み込み
040:    		try {
041:    			// inname(入力画像)を読み込んでimgにセット
042:    			img = ImageIO.read( new File( inname ) );
043:    		} catch (Exception e) {
044:    			// inname(入力画像)の読み込みに失敗したときの処理
045:    			 e.printStackTrace();
046:    			return;
047:    		}
048:    
049:    
050:    		// 画像の横方向のピクセル数をwidthに代入
051:    		width = img.getWidth();
052:    
053:    		// 画像の縦方向のピクセル数をheightに代入
054:    		height = img.getHeight();
055:    
056:    
057:    		// 指定した色のピクセルを数える
058:    		int r, g, b, color;
059:    		int number;
060:    
061:    		number = 0;
062:    		for ( int y = 0; y < height; y++ ) {
063:    			for ( int x = 0; x < width; x++ ) {
064:    				// 色を取得
065:    				color = img.getRGB( x, y );
066:    
067:    				// 色をr,g,bに分解
068:    				r = ( color >> 16 ) & 0xff;
069:    				g = ( color >> 8 ) & 0xff;
070:    				b = color & 0xff;
071:    
072:    				// 色の判定
073:    				if ( ( rn == r ) && ( gn == g ) && ( bn == b ) )
074:    					++ number;
075:    			}
076:    		}
077:    
078:    		// 結果を表示
079:    		System.out.println( "全ピクセル数 : " + width * height );
080:    		System.out.println( "ピクセル数 : " + number );
081:    	}
082:    }

NumberOfPixelsを実行

java NumberOfPixels numberofpixels.png 0 0 0

1つ目の引数で渡した画像ファイルの中に入っているピクセル画素)のうち、2~4目の引数で指定したRGB値と同じいろのものを数えます。

この実行例では、2~4目の引数は全て0なので黒色(R=G=B=0)の数を数えます。

NumberOfPixels.javaの出力結果

・元の画像(numberofpixels.png)

元画像
全ピクセル数 : 128000
ピクセル数 : 83969

画像全体のピクセル数と、指定色(黒)と同じピクセル数を出力しています。

ここからは、このソースコードを上から順番に解説していきます。

001:    import java.awt.image.BufferedImage;
002:    import java.io.File;
003:    import javax.imageio.ImageIO;
004:    import java.io.IOException;

Javaクラスライブラリの中から「java.awt.image.BufferedImage」と「java.io.File」と「javax.imageio.ImageIO」と「java.io.IOException」というパッケージにあるクラスを、このプログラム内で使うために記述します。 この記述により、ImageIOクラスBufferedImageクラスが利用できるようになります。

006:    public class NumberOfPixels {

クラス名を、NumberOfPixelsとしています。

007:    	public static void main( String[] args ) {

このmainメソッドからプログラムを実行します。

008:    		// 画像サイズ
009:    		int width, height;
010:    		// カウントする色
011:    		int rn, gn, bn;
012:    		// ファイル名
013:    		String inname;
014:    		// 画像格納クラス
015:    		BufferedImage img = null;

このプログラムで使う変数を宣言しています。どのように使われているかは、後ろのソースコードで。

017:    		// 入力した引数が4つ以上かを調べる
018:    		if ( 4 > args.length ) {
019:    			// 入力した引数が4つ未満の場合、使用方法を表示する
020:    			System.out.println( "NumberOfPixels [入力画像名] [R] [G] [B]" );
021:    			return;
022:    		}

4つ以上の引数が与えられたかをチェックし、4つ未満の場合に、使い方のメッセージを表示し、returnによってmainメソッドを抜けています。

024:    		// 入力画像名をinnameに代入(拡張子省略なし)
025:    		inname  = args[ 0 ];
026:    
027:    		// 指定色を代入
028:    		try {
029:    			rn = Integer.valueOf( args[ 1 ] );
030:    			gn = Integer.valueOf( args[ 2 ] );
031:    			bn = Integer.valueOf( args[ 3 ] );
032:    		}
033:    		catch( NumberFormatException ne )
034:    		{
035:    			System.out.println( "引数が不正です" );
036:    			return;
037:    		}

与えられた引数を代入しています。画像ファイル名とRGBの値です。

039:    		// 画像の読み込み
040:    		try {
041:    			// inname(入力画像)を読み込んでimgにセット
042:    			img = ImageIO.read( new File( inname ) );
043:    		} catch (Exception e) {
044:    			// inname(入力画像)の読み込みに失敗したときの処理
045:    			 e.printStackTrace();
046:    			return;
047:    		}

入力J画像名の変数(inname)を読み込んで、BufferedImageクラスのimgに格納しています。この処理には、ImageIOクラスreadメソッドを使います。

ImageIO.readメソッド

public static BufferedImage read( File input ) throws IOException
■Fileオブジェクトを復元した結果をBufferedImageに格納します。

  パラメータ input : Fileオブジェクト

  戻り値     inputを復元したBufferedImageaを返します。

try { ~ } catchは、失敗する可能性がある処理を波括弧で囲み、その処理に失敗したときにcatch { ~ }の波括弧で囲まれた処理を実行するということです。この場合は、JPEGファイル名が不正であったり、存在していなかったり、フォーマットが違っているなどが原因で処理が失敗する可能性があります。処理が失敗するとreturnによってmainメソッドを抜けるようにしています。

036:    			return;
037:    		}
038:    
039:    		// 画像の読み込み
040:    		try {
041:    			// inname(入力画像)を読み込んでimgにセット
042:    			img = ImageIO.read( new File( inname ) );

BufferedImageクラスgetTypeメソッド画像のイメージ型を取得しています。

BufferedImage.getTypeメソッド

public static int getType()
■イメージ型を返します。
  パラメータ なし

  戻り値     BufferedImage のイメージ型を返します。

050:    		// 画像の横方向のピクセル数をwidthに代入
051:    		width = img.getWidth();
052:    
053:    		// 画像の縦方向のピクセル数をheightに代入
054:    		height = img.getHeight();

widthに画像の幅(ピクセル)、heightに画像の高さ(ピクセル)を代入しています。

057:    		// 指定した色のピクセルを数える
058:    		int r, g, b, color;
059:    		int number;

指定色のピクセル数を数える処理で使う変数を宣言しています。

061:    		number = 0;

指定色のピクセル数を格納する変数numberに初期値の0を代入しています。

062:    		for ( int y = 0; y < height; y++ ) {
063:    			for ( int x = 0; x < width; x++ ) {
064:    				// 色を取得
065:    				color = img.getRGB( x, y );

画像の中の全てのピクセルの座標を参照するループをつくり、その座標色情報を取得しています。具体的には、変数yを0~height-1、変数xを0~width-1に変化させながら、BufferedImageクラスgetRGBメソッドで、(x,y)の色を変数colorに代入しています。

BufferedImage.getRGBメソッド

public static int getRGB( int x, int y )
■(x,y)で指定した画像座標の色情報を取得します。

  パラメータ x : 画像のx座標(単位ピクセル)
        y : 画像のy座標(単位ピクセル)

  戻り値     (x,y)の色情報

067:    				// 色をr,g,bに分解
068:    				r = ( color >> 16 ) & 0xff;
069:    				g = ( color >> 8 ) & 0xff;
070:    				b = color & 0xff;

変数colorに入っている色情報を赤(R)、緑(G)画、青(B)の成分に分解し、それぞれ変数r、g、bに代入しています。

色の分解方法の詳細はこちらを参照してください。「色をARGB値に分解」

072:    				// 色の判定
073:    				if ( ( rn == r ) && ( gn == g ) && ( bn == b ) )
074:    					++ number;

指定したRGBの値(rn、gn、bn)とピクセルの色(r、g、b)が同じであれば変数numberを1足しています。(numberをインクリメント

078:    		// 結果を表示
079:    		System.out.println( "全ピクセル数 : " + width * height );
080:    		System.out.println( "ピクセル数 : " + number );

全ての処理が正常終了すると、ここまで処理が実行されます。画像の全ピクセル数と指定色のピクセルprintlnコンソール出力しています。

以上です。

■関連コンテンツ

画像の色 画像の色について解説
画像ファイル形式 画像ファイル形式について解説
インクリメント・デクリメント演算子 インクリメント、デクリメント演算子について解説
光と色の3原色の考え方を解説-画像

光と色の3原色

光の3色(RGB)の混合と、インクの3色(CMY)の混合の考え方を説明しています。

画素について説明-画像

画素

画素とは、デジタル画像データを構成している色情報を持った点のことです。

繰り返し処理に使用するfor文について解説-画像

for文

繰り返し処理に使用するfor文をJavaのソースコードを使って説明しています。

条件による処理の分岐に使用するif文について解説-画像

if文

条件による処理の分岐に使用するif文について解説

for文の中にfor文-画像

多重ループ

for文などのループの中にループをいれたプログラムの構造、多重ループについて説明しています。

■新着情報

2022.07.07 外部プログラムの実行 exeファイル実行
2022.07.06 完全数 6=1+2+3

■広告

 

 

 

 

 

スッキリわかるJava入門第3版 [ 中山清喬 ]

価格:2,860円
(2021/6/18 14:32時点)
感想(6件)

 

 

 

 

Topへ