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

2020/03/23 公開

・画像の2倍拡大

ここでは、フルカラー(24bit)画像を縦横のサイズを2倍の画像に変換するソースコードを解説します。ここでは、1つのピクセルの大きさを2x2の4ピクセルにするという最も簡単な方法を紹介します。

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

Expand1.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 Expand1 {
007:    	public static void main( String[] args ) {
008:    		// 結果格納フラグ
009:    		boolean result;
010:    		// ファイル名
011:    		String inname, outname;
012:    		// 画像格納クラス
013:    		BufferedImage img = null;
014:    		BufferedImage newimg = null;
015:    
016:    		// 入力した引数が2つ以上かを調べる
017:    		if ( 2 > args.length ) {
018:    			// 入力した引数が2つ未満の場合、使用方法を表示する
019:    			System.out.println( "Expand1 [入力PNG名]  [出力PNG名]" );
020:    			return;
021:    		}
022:    
023:    		// 入力PNG名をinnameに代入(拡張子".png"省略なし)
024:    		inname  = args[ 0 ];
025:    		// 出力PNG名をoutnameに代入(拡張子".png"省略なし)
026:    		outname = args[ 1 ];
027:    
028:    		try {
029:    			// inname(入力PNG)を読み込んでimgにセット
030:    			img = ImageIO.read( new File( inname ) );
031:    		} catch (Exception e) {
032:    			// inname(入力PNG)の読み込みに失敗したときの処理
033:    			 e.printStackTrace();
034:    			return;
035:    		}
036:    
037:    		// 2倍拡大
038:    		int x, y;
039:    		int width, height;
040:    		int neww, newh;
041:    		int color;
042:    		int newcolor;
043:    
044:    		// 元画像サイズの取得
045:    		width = img.getWidth();
046:    		height= img.getHeight();
047:    
048:    		// 新しい画像サイズを計算
049:    		neww = width * 2;
050:    		newh = height * 2;
051:    
052:    		// 新しい画像を作成
053:    		// 24ビットカラーの画像を作成
054:    		try {
055:    			newimg = new BufferedImage( neww, newh,
056:    						 BufferedImage.TYPE_INT_RGB );
057:    		} catch ( Exception e ) {
058:    			// 画像作成に失敗したときの処理
059:    			e.printStackTrace();
060:    			return;
061:    		}
062:    
063:    		// 処理本体
064:    		for ( y = 0; y < height; ++ y ) {
065:    			for ( x = 0; x < width; ++ x ) {
066:    				// (x,y)の色を取得
067:    				color = img.getRGB( x, y );
068:    
069:    				// 2x2の4倍に拡大
070:    				newimg.setRGB( x * 2,     y * 2,     color );
071:    				newimg.setRGB( x * 2 + 1, y * 2,     color );
072:    				newimg.setRGB( x * 2,     y * 2 + 1, color );
073:    				newimg.setRGB( x * 2 + 1, y * 2 + 1, color );
074:    			}
075:    		}
076:    
077:    		try {
078:    			// imgをoutname(出力PNG)に保存
079:    			result = ImageIO.write( newimg, "png", new File( outname ) );
080:    		} catch ( Exception e ) {
081:    			// outname(出力PNG)の保存に失敗したときの処理
082:    			e.printStackTrace();
083:    			return;
084:    		}
085:    
086:    		// 正常に終了
087:    		System.out.println( "正常に終了しました" );
088:    	}
089:    }

Expand1を実行

C:\talavax\javasample>java Expand1 sampleimage002_200x150.png expand1.png

1つ目の引数で渡したPNGファイルを2倍に拡大し、2つ目の引数で指定したPNGファイル名で保存します。

実行結果

・元の画像(sampleimage002_200x150.png)

元画像

・2倍に拡大した画像(expand1.png)

>2倍拡大画像

画像のサイズが、縦横2倍になりました。

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

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 Expand1 {

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

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

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

008:    		// 結果格納フラグ
009:    		boolean result;
010:    		// ファイル名
011:    		String inname, outname;
012:    		// 画像格納クラス
013:    		BufferedImage img = null;
014:    		BufferedImage newimg = null;

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

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

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

023:    		// 入力PNG名をinnameに代入(拡張子".png"省略なし)
024:    		inname  = args[ 0 ];
025:    		// 出力PNG名をoutnameに代入(拡張子".png"省略なし)
026:    		outname = args[ 1 ];

与えられた引数をそれぞれ、入力PNG名の変数(inname)、出力PNG名の変数(outname)代入しています。

028:    		try {
029:    			// inname(入力PNG)を読み込んでimgにセット
030:    			img = ImageIO.read( new File( inname ) );
031:    		} catch (Exception e) {
032:    			// inname(入力PNG)の読み込みに失敗したときの処理
033:    			 e.printStackTrace();
034:    			return;
035:    		}

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

ImageIO.readメソッド

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

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

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

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

037:    		// 2倍拡大
038:    		int x, y;
039:    		int width, height;
040:    		int neww, newh;
041:    		int color;
042:    		int newcolor;

画像の2倍拡大で使う変数を宣言しています。

044:    		// 元画像サイズの取得
045:    		width = img.getWidth();
046:    		height= img.getHeight();

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

048:    		// 新しい画像サイズを計算
049:    		neww = width * 2;
050:    		newh = height * 2;

2倍拡大された結果の画像のサイズを計算しています。newwに幅ピクセルの2倍、newhに高さピクセルの2倍の値を代入しています。

052:    		// 新しい画像を作成
053:    		// 24ビットカラーの画像を作成
054:    		try {
055:    			newimg = new BufferedImage( neww, newh,
056:    						 BufferedImage.TYPE_INT_RGB );
057:    		} catch ( Exception e ) {
058:    			// 画像作成に失敗したときの処理
059:    			e.printStackTrace();
060:    			return;
061:    		}

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

BufferedImageコンストラクタ

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

imgTypeで指定しているTYPE_INT_RGBは、整数ピクセルにパックされた 8 ビット RGB 色成分によるイメージを表します。これを指定することで24ビット画像を作成できます。

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

このソースプログラムの例では、入力PNGの色の深さが32ビット(透明色付き)であっても、24ビット画像に変換するので透明色の情報は消去されます。

063:    		// 処理本体
064:    		for ( y = 0; y < height; ++ y ) {
065:    			for ( x = 0; x < width; ++ x ) {
066:    				// (x,y)の色を取得
067:    				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)の色情報

069:    				// 2x2の4倍に拡大
070:    				newimg.setRGB( x * 2,     y * 2,     color );
071:    				newimg.setRGB( x * 2 + 1, y * 2,     color );
072:    				newimg.setRGB( x * 2,     y * 2 + 1, color );
073:    				newimg.setRGB( x * 2 + 1, y * 2 + 1, color );

変数colorに入っている色情報を2x2の4倍に拡大していいます。

ピクセルの拡大

077:    		try {
078:    			// imgをoutname(出力PNG)に保存
079:    			result = ImageIO.write( newimg, "png", new File( outname ) );
080:    		} catch ( Exception e ) {
081:    			// outname(出力PNG)の保存に失敗したときの処理
082:    			e.printStackTrace();
083:    			return;
084:    		}

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

ImageIO.wrireメソッド

public static boolean write( RenderedImage im, String formatName, File output ) throws IOException
■BufferedImageを画像ファイルに保存します。

  パラメータ RenderedImage : 保存するRenderedImage
                  formatName     : 画像ファイルのフォーマット(png/jpeg/bmp/gifなど)
                  output             : Fileオブジェクト

  戻り値     保存に成功するとtrue、失敗するとfalseを返します。

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

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

以上です。

■関連コンテンツ

画像の色 画像の色について解説
画像ファイル形式 画像ファイル形式について解説
光と色の3原色の考え方を解説-画像

光と色の3原色

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

画素について説明-画像

画素

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

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

for文

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

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へ