2019/06/18 公開
・同心円模様
画像サイズと黒の線幅と白の線幅を指定することで、黒と白の同心縁模様画像を作成します。ここで紹介するプログラムで出力する画像の形式はPNGファイルです。
上の画像の例は、画像サイズ:256x256、黒のピクセル幅:10、白のピクセル幅:20で作成したものです。この例では、中心付近の色は白色になるようにしています。
Pattern_Circles01.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_Circles01 { 007: public static void main( String[] args ) { 008: // 変数宣言 009: int w, h; // 画像サイズ 010: int w_b; // 黒の幅 011: int w_w; // 白の幅 012: String outname; // 出力ファイル名 013: BufferedImage img = null; // 画像格納クラス 014: 015: // 入力した引数が5以上かを調べる 016: if ( 5 > args.length ) { 017: // 入力した引数が5未満の場合、使用方法を表示する 018: System.out.println( 019: "Pattern_Circles01 [PNG名] [画像幅] [画像高] [黒幅] [白幅]" ); 020: return; 021: } 022: 023: try { 024: // 引数を変換し、画像の幅と高さをwとhに代入 025: w = Integer.valueOf( args[ 1 ] ); 026: h = Integer.valueOf( args[ 2 ] ); 027: 028: // 引数を変換し、黒の幅w_bに代入 029: w_b = Integer.valueOf( args[ 3 ] ); 030: if ( 1 > w_b ) { 031: System.out.println( "黒幅に1以上を指定!" ); 032: return; 033: } 034: 035: // 引数を変換し、白の幅w_wに代入 036: w_w = Integer.valueOf( args[ 4 ] ); 037: if ( 1 > w_w ) { 038: System.out.println( "白幅に1以上を指定!" ); 039: return; 040: } 041: } 042: catch( NumberFormatException ne ) 043: { 044: System.out.println( "引数が不正です" ); 045: return; 046: } 047: // 出力PNG名をoutnameに代入(拡張子".png"省略なし) 048: outname = args[ 0 ]; 049: 050: // 新しい画像を作成 051: // 24ビットカラーの画像を作成 052: try { 053: img = new BufferedImage( w, h, 054: BufferedImage.TYPE_INT_RGB ); 055: } catch ( Exception e ) { 056: // 画像作成に失敗したときの処理 057: e.printStackTrace(); 058: return; 059: } 060: 061: // 同心円画像作成 062: int x, y; 063: int color, r, g, b; // 計算した色 064: double ox, oy; // 画像の中心座標 065: double l; // 画像の中心座標からの距離 066: double dx, dy; // 画像の中心座標からの距離(x,y毎) 067: 068: // 画像の中心座標を計算 069: ox = (double)( w - 1 ) / 2.0; 070: oy = (double)( h - 1 ) / 2.0; 071: 072: // 画像の作成メインループ 073: for ( y = 0; y < h; ++ y ) { 074: // 中心座標oyからのyまでの距離 075: dy = (double)y - oy; 076: 077: for ( x = 0; x < w; ++ x ) { 078: // 中心座標oxからのxまでの距離 079: dx = (double)x - ox; 080: 081: // 中心座標からの距離計算 082: l = Math.sqrt( dx * dx + dy * dy ); 083: 084: // 黒か白かの判定 085: if ( ( l % (double)( w_b + w_w ) ) <= (double)w_w ) 086: r = g = b = 255; 087: else 088: r = g = b = 0; 089: 090: // r,g,bの色を合成 091: color = ( r << 16 ) + ( g << 8 ) + b; 092: 093: // 合成した色を(x,y)に設定 094: img.setRGB( x, y, color ); 095: } 096: } 097: 098: try { 099: // imgをoutname(出力PNG)に保存 100: boolean result; 101: result = ImageIO.write( img, "PNG", new File( outname ) ); 102: } catch ( Exception e ) { 103: // outname(出力PNG)の保存に失敗したときの処理 104: e.printStackTrace(); 105: return; 106: } 107: 108: // 正常に終了 109: System.out.println( "正常に終了しました" ); 110: } 111: }
Pattern_Circles01の実行例
java Pattern_Circles01 pattern_circles01.png 256 256 20 10
ここからは、この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_Circles01 {
クラス名を、Pattern_Circles01としています。
007: public static void main( String[] args ) {
このmainメソッドからプログラムを実行します。
008: // 変数宣言 009: int w, h; // 画像サイズ 010: int w_b; // 黒の幅 011: int w_w; // 白の幅 012: String outname; // 出力ファイル名 013: BufferedImage img = null; // 画像格納クラス
このプログラムで使う変数を宣言しています。
015: // 入力した引数が5以上かを調べる 016: if ( 5 > args.length ) { 017: // 入力した引数が5未満の場合、使用方法を表示する 018: System.out.println( 019: "Pattern_Circles01 [PNG名] [画像幅] [画像高] [黒幅] [白幅]" ); 020: return; 021: }
5つ以上の引数が与えられたかをチェックし、5つ未満の場合に、使い方のメッセージを表示し、returnによってmainメソッドを抜けています。
023: try { 024: // 引数を変換し、画像の幅と高さをwとhに代入 025: w = Integer.valueOf( args[ 1 ] ); 026: h = Integer.valueOf( args[ 2 ] ); 027: 028: // 引数を変換し、黒の幅w_bに代入 029: w_b = Integer.valueOf( args[ 3 ] ); 030: if ( 1 > w_b ) { 031: System.out.println( "黒幅に1以上を指定!" ); 032: return; 033: } 034: 035: // 引数を変換し、白の幅w_wに代入 036: w_w = Integer.valueOf( args[ 4 ] ); 037: if ( 1 > w_w ) { 038: System.out.println( "白幅に1以上を指定!" ); 039: return; 040: } 041: } 042: catch( NumberFormatException ne ) 043: { 044: System.out.println( "引数が不正です" ); 045: return; 046: } 047: // 出力PNG名をoutnameに代入(拡張子".png"省略なし) 048: outname = args[ 0 ];
与えられた引数をそれぞれ、作成する画像の幅/高さ、黒ピクセルの幅、白ピクセルの幅、出力PNG名を格納する変数に代入しています。画像の幅/高さ、黒ピクセルの幅、白ピクセルの幅の引数はString型なので、Integerクラスを使ってint型に変換しています。
050: // 新しい画像を作成 051: // 24ビットカラーの画像を作成 052: try { 053: img = new BufferedImage( w, h, 054: BufferedImage.TYPE_INT_RGB ); 055: } catch ( Exception e ) { 056: // 画像作成に失敗したときの処理 057: e.printStackTrace(); 058: return; 059: }
BufferedImageクラスのコンストラクタで、新しいBufferedImageを構築しています。
BufferedImageコンストラクタ
■新しい BufferedImage を構築します。 パラメータ width : 構築する画像の横ピクセル height : 構築する画像の縦ピクセル imageType : 構築する画像のイメージ形式
061: // 同心円画像作成 062: int x, y; 063: int color, r, g, b; // 計算した色 064: double ox, oy; // 画像の中心座標 065: double l; // 画像の中心座標からの距離 066: double dx, dy; // 画像の中心座標からの距離(x,y毎)
068: // 画像の中心座標を計算 069: ox = (double)( w - 1 ) / 2.0; 070: oy = (double)( h - 1 ) / 2.0;
画像の中心座標を計算しています。画像の座標の範囲は、左上(0,0)~右下(w-1,h-1)なので、(w-1)と(h-1)を2で割った値が画像の中心座標になります。
画像の中心座標の計算方法はこちらを参照してください。「画像の中心座標」
072: // 画像の作成メインループ 073: for ( y = 0; y < h; ++ y ) { 074: // 中心座標oyからのyまでの距離 075: dy = (double)y - oy; 076: 077: for ( x = 0; x < w; ++ x ) { 078: // 中心座標oxからのxまでの距離 079: dx = (double)x - ox; 080: 081: // 中心座標からの距離計算 082: l = Math.sqrt( dx * dx + dy * dy ); 083: 084: // 黒か白かの判定 085: if ( ( l % (double)( w_b + w_w ) ) <= (double)w_w ) 086: r = g = b = 255; 087: else 088: r = g = b = 0; 089: 090: // r,g,bの色を合成 091: color = ( r << 16 ) + ( g << 8 ) + b; 092: 093: // 合成した色を(x,y)に設定 094: img.setRGB( x, y, color ); 095: } 096: }
画像の中の全てのピクセルの座標(x,y)を参照するループをつくり、その座標の色が黒か白かを判定していきます。判定した色を(x,y)に代入していきます。
判定には、画像の中心座標(ox,oy)と(x,y)を結んだ線の距離lを使います。
求めた距離lを(黒ピクセル幅+白ピクセル幅)で割った余りを求め、その値が白ピクセル幅以下であれば白色とし、超えていれば黒色としています。
098: try { 099: // imgをoutname(出力PNG)に保存 100: boolean result; 101: result = ImageIO.write( img, "PNG", new File( outname ) ); 102: } catch ( Exception e ) { 103: // outname(出力PNG)の保存に失敗したときの処理 104: e.printStackTrace(); 105: return; 106: }
BufferedImageクラスのimgのメモリ内のデータを、出力PNG名の変数(outname)に格納されているファイル名で保存します。この場合は、PNGファイル名が不正であったり、保存先のHDDなどが存在していなかったり、空き容量が少ないなどが原因で処理が失敗する可能性があります。
108: // 正常に終了 109: System.out.println( "正常に終了しました" );
全ての処理が正常終了すると、ここまで処理が実行されます。
以上です。
■関連コンテンツ
模様の描画 | いろいろな模様の描画方法を紹介 |
2点間の距離 | 2点間の距離計算 |
画像の座標系 | 画像の座標系について解説 |
画像の中心座標 | 画像の中心座標は? |
円を描く(テキスト版) | テキストを円を描く |
タイル画像の素材 | フリーの素材を提供 |
■新着情報
2022.07.07 | 外部プログラムの実行 | exeファイル実行 |
2022.07.06 | 完全数 | 6=1+2+3 |
■広告