2017/08/27 公開
・テーブルによる色変換
色変換テーブルは、RGBそれぞれの色成分(0~255の整数)を入力したときの出力値を設定したテーブルのことです。下の図は、入力値RGBを出力値R'G'B'に変換するイメージです。

具体的には、テーブルとしてRGB各成分ごとに定義したint型の配列をテーブルを使います。
int[] colorconv_r = new int[ 256 ]; int[] colorconv_g = new int[ 256 ]; int[] colorconv_b = new int[ 256 ];
配列の添え字が入力値で、配列の値が出力値です。配列の値は、0~255の範囲に収まるように設定しておきます。以下のソースは、入力値rとgとbのそれぞれの色成分を出力値に変換している例です。
r = colorconv_r[ r ]; g = colorconv_g[ g ]; b = colorconv_b[ b ];
配列に設定するだけで、簡単に色変換できることが分かります。ただし、RGBを組み合わせて色を計算するグレースケール変換や2値化、セピア色への変換等にはこの方法は使用できません。
これから紹介するJavaソースコードには、テーブルを利用した色変換の例をいくつか含んでいます。それらの色変換は、引数で渡すモードによって変えられるようにしています。参考にしてください。
ColorConversion.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 ColorConversion { 007: // modeによるカラーテーブルの設定 008: static void setTable( int[] colorconv_r, int[] colorconv_g, int[] colorconv_b, 009: int mode ) 010: { 011: int i, col; 012: double rad; 013: 014: switch ( mode ) { 015: case 0: 016: // 色反転 017: for ( i = 0; i < 256; ++ i ) { 018: colorconv_r[ i ] = 255 - i; 019: colorconv_g[ i ] = 255 - i; 020: colorconv_b[ i ] = 255 - i; 021: } 022: break; 023: 024: case 1: 025: // 輝度を半分 026: for ( i = 0; i < 256; ++ i ) { 027: colorconv_r[ i ] = i / 2; 028: colorconv_g[ i ] = i / 2; 029: colorconv_b[ i ] = i / 2; 030: } 031: break; 032: 033: case 2: 034: // 量子化 035: for ( i = 0; i < 256; ++ i ) { 036: colorconv_r[ i ] = ( i / 64 ) * 64; 037: colorconv_g[ i ] = ( i / 64 ) * 64; 038: colorconv_b[ i ] = ( i / 64 ) * 64; 039: } 040: break; 041: 042: case 3: 043: // サインカーブ 044: for ( i = 0; i < 256; ++ i ) { 045: rad = Math.toRadians( (double)i / 256.0 * 720.0 ); 046: col = (int)( Math.sin( rad ) * 127.0 + 127.0 ); 047: colorconv_r[ i ] = col; 048: colorconv_g[ i ] = col; 049: colorconv_b[ i ] = col; 050: } 051: break; 052: 053: case 4: 054: // 白っぽくする 055: for ( i = 0; i < 256; ++ i ) { 056: colorconv_r[ i ] = i + 100; 057: if ( 255 < colorconv_r[ i ] ) colorconv_r[ i ] = 255; 058: colorconv_g[ i ] = i + 100; 059: if ( 255 < colorconv_g[ i ] ) colorconv_g[ i ] = 255; 060: colorconv_b[ i ] = i + 100; 061: if ( 255 < colorconv_b[ i ] ) colorconv_b[ i ] = 255; 062: } 063: break; 064: 065: 066: case 5: 067: // 赤成分だけの残す 068: for ( i = 0; i < 256; ++ i ) { 069: colorconv_r[ i ] = i; 070: colorconv_g[ i ] = 0; 071: colorconv_b[ i ] = 0; 072: } 073: break; 074: 075: 076: case 6: 077: // 緑成分だけの残す 078: for ( i = 0; i < 256; ++ i ) { 079: colorconv_r[ i ] = 0; 080: colorconv_g[ i ] = i; 081: colorconv_b[ i ] = 0; 082: } 083: break; 084: 085: 086: case 7: 087: // 青成分だけの残す 088: for ( i = 0; i < 256; ++ i ) { 089: colorconv_r[ i ] = 0; 090: colorconv_g[ i ] = 0; 091: colorconv_b[ i ] = i; 092: } 093: break; 094: 095: default: 096: // 入力値と出力値を同じにする 097: for ( i = 0; i < 256; ++ i ) { 098: colorconv_r[ i ] = i; 099: colorconv_g[ i ] = i; 100: colorconv_b[ i ] = i; 101: } 102: break; 103: } 104: } 105: 106: 107: public static void main( String[] args ) { 108: // 結果格納フラグ 109: boolean result; 110: // 色変換モード 111: int mode; 112: // ファイル名 113: String inname, outname; 114: // 画像格納クラス 115: BufferedImage img = null; 116: 117: // 入力した引数が3つ以上かを調べる 118: if ( 3 > args.length ) { 119: // 入力した引数が3つ未満の場合、使用方法を表示する 120: System.out.println( "ColorConversion [入力JPG][出力JPG][モード]" ); 121: return; 122: } 123: 124: // 入力JPEG名をinnameに代入(拡張子".jpg"省略なし) 125: inname = args[ 0 ]; 126: // 出力JPEG名をoutnameに代入(拡張子".jpg"省略なし) 127: outname = args[ 1 ]; 128: 129: // モードをmodeに代入 130: try { 131: // 引数を変換し、モードに代入 132: mode = Integer.valueOf( args[ 2 ] ); 133: } 134: catch( NumberFormatException ne ) 135: { 136: System.out.println( "引数が不正です" ); 137: return; 138: } 139: 140: // JPEGの読み込み 141: try { 142: // inname(入力JPEG)を読み込んでimgにセット 143: img = ImageIO.read( new File( inname ) ); 144: } catch (Exception e) { 145: // inname(入力JPEG)の読み込みに失敗したときの処理 146: e.printStackTrace(); 147: return; 148: } 149: 150: 151: // 画像の色の持ち方をチェック 152: if ( BufferedImage.TYPE_3BYTE_BGR != img.getType() ) 153: { 154: System.out.println( "対応していないカラーモデルです!(" 155: + inname +")" ); 156: return; 157: } 158: 159: // 色変換 160: int x, y; 161: int width, height; 162: int color, r, g, b; 163: int p; 164: int newcolor; 165: 166: // 色変換テーブル 167: int[] colorconv_r = new int[ 256 ]; 168: int[] colorconv_g = new int[ 256 ]; 169: int[] colorconv_b = new int[ 256 ]; 170: 171: 172: // 色変換テーブル設定 173: setTable( colorconv_r, colorconv_g, colorconv_b, mode ); 174: 175: // 画像サイズの取得 176: width = img.getWidth(); 177: height= img.getHeight(); 178: 179: for ( y = 0; y < height; ++ y ) { 180: for ( x = 0; x < width; ++ x ) { 181: // (x,y)の色を取得 182: color = img.getRGB( x, y ); 183: 184: // 色をr,g,bに分解 185: r = ( color >> 16 ) & 0xff; 186: g = ( color >> 8 ) & 0xff; 187: b = color & 0xff; 188: 189: // r,g,bの色をテーブルで変換 190: r = colorconv_r[ r ]; 191: g = colorconv_g[ g ]; 192: b = colorconv_b[ b ]; 193: 194: // r,g,bの色を合成 195: newcolor = ( r << 16 ) + ( g << 8 ) + b; 196: 197: // 合成した色を(x,y)に設定 198: img.setRGB( x, y, newcolor ); 199: } 200: } 201: 202: try { 203: // imgをoutname(出力JPEG)に保存 204: result = ImageIO.write( img, "jpeg", new File( outname ) ); 205: } catch ( Exception e ) { 206: // outname(出力JPEG)の保存に失敗したときの処理 207: e.printStackTrace(); 208: return; 209: } 210: 211: // 正常に終了 212: System.out.println( "正常に終了しました" ); 213: } 214: }
ColorConversionを実行
>java ColorConversion sampleimage005_300x200.jpg colorconversion_0001.jpg 1
1つ目の引数で元のJPEGファイル名、2つ目の引数に作成するJPEG画像ファイル名、3つ目に色変換モードを指定します。
実行結果
・元の画像(sampleimage005_300x200.jpg)

・モード=0で作成した画像(colorconversion_0000.jpg)

・モード=1で作成した画像(colorconversion_0001.jpg)

・モード=2で作成した画像(colorconversion_0002.jpg)

・モード=3で作成した画像(colorconversion_0003.jpg)

・モード=4で作成した画像(colorconversion_0004.jpg)

・モード=5で作成した画像(colorconversion_0005.jpg)

・モード=6で作成した画像(colorconversion_0006.jpg)

・モード=7で作成した画像(colorconversion_0007.jpg)

モードによっていろいろな処理の画像が作成されることが分かります。
■関連コンテンツ
テーブルによる色変換 その2 | テーブルによる色の変換方法を解説(その2) |
テーブルによる色変換 その3 | テーブルによる色の変換方法を解説(その3) |
Javaの配列 | 同じ型の変数をまとめた配列について解説 |
■新着情報
2022.07.07 | 外部プログラムの実行 | exeファイル実行 |
2022.07.06 | 完全数 | 6=1+2+3 |
■広告
