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 を構築します。 パラメータ 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 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文をJavaのソースコードを使って説明しています。 |
![]() |
剰余(余り)計算剰余(余り)をを計算するプログラムの紹介と、その結果を表示する方法を解説 |
■新着情報
2022.07.07 | 外部プログラムの実行 | exeファイル実行 |
2022.07.06 | 完全数 | 6=1+2+3 |
■広告
