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

2019/11/11 公開

・塗りつぶし円

画像の幅と高さを指定することで、黒く塗りつぶした円を描画した画像を作成します。ここで紹介するプログラムで出力する画像の形式はPNGファイルです。

塗りつぶし円画像塗りつぶし円画像

上の画像の例は、画像サイズ:256x256で作成したものです。

ここから、塗りつぶした円の作り方を説明していきます。

このプログラムでは、パラメーターで円の半径ピクセル数を指定せずに、画像のサイズから円の半径を求めます。指定した画像の幅と高さのピクセルを比較して、小さい方の値を2で割ったものを円の半径ピクセル数にしています。

続いて、画像の中心座標(mx,my)を求めます。これは、画像の幅から1を引いて2で割った値をmx、画像の高さから1を引いて2で割った値をmyとします。下の図は、画像サイズから中心座標(mx,my)の関係を表したものです。

画像の中心座標の計算

次に、画像の全ての座標(x,y)と中心座標(mx,my)との直線距離を計算し、その値が半径以下であれば円の中の座標と判定し、黒色のピクセルを(x,y)に描画します。円の外と判定された場合、白色のピクセルを描画します。

これで塗りつぶした円が描画されます。

以下が、円の塗りつぶし画像を作成するJavaのソースコード例です。

Pattern_Circle00.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 Pattern_Circle00 {
007:    	// メイン
008:    	public static void main( String[] args ) {
009:    		// 変数宣言
010:    		int w, h;	// 画像サイズ
011:    		String outname;	// 出力ファイル名
012:    		BufferedImage img = null;	// 画像格納クラス
013:    
014:    		// 入力した引数が3以上かを調べる
015:    		if ( 3 > args.length ) {
016:    			// 入力した引数が3未満の場合、使用方法を表示する
017:    			System.out.println( 
018:    				"Pattern_Circle00 [PNG名] [画像幅] [画像高]" );
019:    			return;
020:    		}
021:    
022:    		try {
023:    			// 引数を変換し、画像の幅と高さをwとhに代入
024:    			w =  Integer.valueOf( args[ 1 ] );
025:    			h =  Integer.valueOf( args[ 2 ] );
026:    		}
027:    		catch( NumberFormatException ne )
028:    		{
029:    			System.out.println( "引数が不正です" );
030:    			return;
031:    		}
032:    		// 出力PNG名をoutnameに代入(拡張子".png"省略なし)
033:    		outname = args[ 0 ];
034:    
035:    		// 新しい画像を作成
036:    		// 24ビットカラーの画像を作成
037:    		try {
038:    			img = new BufferedImage( w, h,
039:    						 BufferedImage.TYPE_INT_RGB );
040:    		} catch ( Exception e ) {
041:    			// 画像作成に失敗したときの処理
042:    			e.printStackTrace();
043:    			return;
044:    		}
045:    
046:    		// 円画像作成
047:    		int    x, y;
048:    		int    color, r, g, b;	// 計算した色
049:    		double mx, my;		// 画像の中心座標
050:    		double l;		// 画像の中心座標からの距離
051:    		double dx, dy;		// 画像の中心座標からの距離(x,y毎)
052:    		double radius;		// 半径
053:    		double radius2;		// 半径の2乗
054:    	
055:    		// 画像の中心座標を計算
056:    		mx = (double)( w - 1 ) / 2.0;
057:    		my = (double)( h - 1 ) / 2.0;
058:    
059:    		// 円の半径
060:    		radius = (double)Math.min( w, h ) / 2.0;
061:    
062:    		// 円の半径の2乗
063:    		radius2 = radius * radius;
064:    	
065:    		// 画像の作成メインループ
066:    		for ( y = 0; y < h; ++ y ) {
067:    			// 中心座標oyからのyまでの距離
068:    			dy = (double)y - my;
069:    
070:    			for ( x = 0; x < w; ++ x ) {
071:    				// 中心座標oxからのxまでの距離
072:    				dx = (double)x - mx;
073:    
074:    				// 中心座標からの距離計算の2乗
075:    				l = dx * dx + dy * dy;
076:    
077:    				// 白か黒かを判定
078:    				if ( l <= radius2 )
079:    					r = g = b = 0;	// 円の中
080:    				else
081:    					r = g = b = 255;	// 円の外
082:    
083:    				// r,g,bの色を合成
084:    				color = ( r << 16 ) + ( g << 8 ) + b;
085:    
086:    				// 合成した色を(x,y)に設定
087:    				img.setRGB( x, y, color );
088:    			}
089:    		}
090:    
091:    		try {
092:    			// imgをoutname(出力PNG)に保存
093:    			boolean result;
094:    			result = ImageIO.write( img, "PNG", new File( outname ) );
095:    		} catch ( Exception e ) {
096:    			// outname(出力PNG)の保存に失敗したときの処理
097:    			e.printStackTrace();
098:    			return;
099:    		}
100:    
101:    		// 正常に終了
102:    		System.out.println( "正常に終了しました" );
103:    	}
104:    }

Pattern_Circle00の実行例

java Pattern_Circle00 pattern_circle00.png 256 256

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

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」というパッケージにあるクラスを、このプログラム内で使うために記述します。この記述により、BufferedImageクラスImageIOクラスが利用できるようになります。

006:    public class Pattern_Circle00 {

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

007:    	// メイン
008:    	public static void main( String[] args ) {

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

009:    		// 変数宣言
010:    		int w, h;	// 画像サイズ
011:    		String outname;	// 出力ファイル名
012:    		BufferedImage img = null;	// 画像格納クラス

このプログラムで使う変数を宣言しています。

015:    		if ( 3 > args.length ) {
016:    			// 入力した引数が3未満の場合、使用方法を表示する
017:    			System.out.println( 
018:    				"Pattern_Circle00 [PNG名] [画像幅] [画像高]" );
019:    			return;
020:    		}

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

022:    		try {
023:    			// 引数を変換し、画像の幅と高さをwとhに代入
024:    			w =  Integer.valueOf( args[ 1 ] );
025:    			h =  Integer.valueOf( args[ 2 ] );
026:    		}
027:    		catch( NumberFormatException ne )
028:    		{
029:    			System.out.println( "引数が不正です" );
030:    			return;
031:    		}
032:    		// 出力PNG名をoutnameに代入(拡張子".png"省略なし)
033:    		outname = args[ 0 ];

与えられた引数をそれぞれ、作成する画像の幅/高さ、出力PNG名を格納する変数に代入しています。画像の幅/高さの引数はString型なので、Integerクラスを使ってint型に変換しています。

035:    		// 新しい画像を作成
036:    		// 24ビットカラーの画像を作成
037:    		try {
038:    			img = new BufferedImage( w, h,
039:    						 BufferedImage.TYPE_INT_RGB );
040:    		} catch ( Exception e ) {
041:    			// 画像作成に失敗したときの処理
042:    			e.printStackTrace();
043:    			return;
044:    		}

BufferedImageクラスコンストラクタで、新しいBufferedImageを構築しています。

BufferedImageコンストラクタ

BufferedImage( int width, int height, int imageType )
■新しい BufferedImage を構築します。
  パラメータ width     : 構築する画像の横ピクセル
        height    : 構築する画像の縦ピクセル
        imageType : 構築する画像のイメージ形式

046:    		// 円画像作成
047:    		int    x, y;
048:    		int    color, r, g, b;	// 計算した色
049:    		double mx, my;		// 画像の中心座標
050:    		double l;		// 画像の中心座標からの距離
051:    		double dx, dy;		// 画像の中心座標からの距離(x,y毎)
052:    		double radius;		// 半径
053:    		double radius2;		// 半径の2乗

画像作成で使う変数を宣言しています。

055:    		// 画像の中心座標を計算
056:    		mx = (double)( w - 1 ) / 2.0;
057:    		my = (double)( h - 1 ) / 2.0;

画像の中心座標を計算しています。画像の座標の範囲は、左上(0,0)~右下(w-1,h-1)なので、(w-1)と(h-1)を2で割った値が画像の中心座標になります。

画像の中心座標の計算方法はこちらを参照してください。「画像の中心座標」

059:    		// 円の半径
060:    		radius = (double)Math.min( w, h ) / 2.0;

描画する円の半径radiusを計算しています。ここでは、画像の幅と高さのピクセルの小さい方を2で割った値を半径としています。

Math.minメソッド

public static int Math.min( int a, int b )
public static long Math.min( long a, long b )
public static float Math.min( float a, float b )
public static double Math.min( double a, double b )
■2つの値のうち小さい方を返します。

  パラメータ a : 1つめの値
        b : 2つめの値

  戻り値     aとbのうち、小さい値

062:    		// 円の半径の2乗
063:    		radius2 = radius * radius;

描画する円の半径2乗した値radius2を計算しています。

065:    		// 画像の作成メインループ
066:    		for ( y = 0; y < h; ++ y ) {
067:    			// 中心座標oyからのyまでの距離
068:    			dy = (double)y - my;
069:    
070:    			for ( x = 0; x < w; ++ x ) {
071:    				// 中心座標oxからのxまでの距離
072:    				dx = (double)x - mx;
073:    
074:    				// 中心座標からの距離計算の2乗
075:    				l = dx * dx + dy * dy;

画像の中の全てのピクセルの座標(x,y)を参照するループfor文でつくり、円の中心座標(mx,my)と(x,y)の距離の2乗を計算しています。

ピタゴラスの定理
077:    				// 白か黒かを判定
078:    				if ( l <= radius2 )
079:    					r = g = b = 0;	// 円の中
080:    				else
081:    					r = g = b = 255;	// 円の外

距離の2乗lが半径2乗radius2以下であれば、(x,y)は中心座標(mx,my)・半径radiusの円の中にいるので黒色(r=g=b=0)にしています。(x,y)が円の外の場合白色(r=g=b=255)にしています。

083:    				// r,g,bの色を合成
084:    				color = ( r << 16 ) + ( g << 8 ) + b;

r、g、bを合成し、colorに格納しています。

086:    				// 合成した色を(x,y)に設定
087:    				img.setRGB( x, y, color );

合成した色(変数color)を(x,y)に代入しています。

091:    		try {
092:    			// imgをoutname(出力PNG)に保存
093:    			boolean result;
094:    			result = ImageIO.write( img, "PNG", new File( outname ) );
095:    		} catch ( Exception e ) {
096:    			// outname(出力PNG)の保存に失敗したときの処理
097:    			e.printStackTrace();
098:    			return;
099:    		}

BufferedImageクラスのimgのメモリ内のデータを、出力PNG名の変数(outname)に格納されているファイル名で保存します。この場合は、PNGファイル名が不正であったり、保存先のHDDなどが存在していなかったり、空き容量が少ないなどが原因で処理が失敗する可能性があります。

101:    		// 正常に終了
102:    		System.out.println( "正常に終了しました" );

全ての処理が正常終了すると、ここまで処理が実行されます。

以上です。

■関連コンテンツ

模様の描画 いろいろな模様の描画方法を紹介
2点間の距離 2点間の距離計算
画像の座標系 画像の座標系について解説
円を描く(テキスト版) テキストを円を描く
画像の中心座標 画像の中心座標は?
タイル画像の素材 フリーの素材を提供
グラデーションを作成する方法を解説-画像

グラデーション

色を段階的に変化させたグラデーション画像を作成する方法を解説しています。

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

for文

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

剰余(余り)を計算した結果を表示するプログラムについて解説-画像

剰余(余り)計算

剰余(余り)をを計算するプログラムの紹介と、その結果を表示する方法を解説

■新着情報

2022.07.06 完全数 6=1+2+3

■広告

 

 

 

 

 

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

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

 

 

 

 

Topへ