[ 前へ | 目次 | 次へ ]
Japanese English
Now Loading...
ダウンロード
PC (※スマートフォンでは動きません) でダウンロードし、ZIPファイルを右クリックメニューから展開して、できたフォルダ内の「 VCSSL.bat(バッチファイル) 」をダブルクリックすると起動します。 Linux等では「 VCSSL.jar 」をコマンド実行してください。
» 詳しい使用方法や、エラーで展開できない際の対応方法などはこちら

RGBやカラーコードの色表示と相互変換ができる簡易ツール

このプログラムは、RGB値やカラーコードから、色の表示や相互変換を行う、VCSSL製の簡易ツールです。

使用方法

ダウンロードと展開(解凍)

まず、PC(スマホは未対応)で上の画面の「 ダウンロード 」ボタンを押してください。 するとZIP形式で圧縮されたファイルがダウンロードされます。

Windows をご使用の方は、ここでまずZIPファイルを右クリックし、「プロパティ」を選んで開かれる画面で、 下の方にあるセキュリティ項目の「許可する」にチェックを入れて「OK」で閉じてください。 これを行わないと、ZIP展開やソフト起動時に、警告メッセージが出て展開完了/起動できない場合があります。

その後、ZIPファイルを右クリックして「すべて展開」や「ここに展開」などで展開(解凍)してください。 展開が成功すると、ZIPファイルと同じ名前のフォルダができ、その中にZIPファイルの中身が入っています。

» 展開がエラーで止まってしまう場合や、ファイル名が文字化けしてしまう場合は…

プログラムの起動

Windows をご使用の場合

上記でZIPファイルを展開したフォルダ内にある、以下のバッチファイルをダブルクリック実行してください:

VCSSL__ダブルクリックでプログラム実行.bat

もしプログラムを書き変えながら使いたい場合は、代わりに「 VCSSL_Editor__プログラム編集はこちら.bat 」を実行してください。

正常に起動できると、初回のみ、Java実行環境を入手するか等を尋ねられるので、適時答えて済ませると、プログラムが起動します。 2回目以降はすぐに起動します。

» うまく起動できずにエラーになってしまう場合は…

Linux 等をご使用の場合

ZIPファイルを展開したフォルダ内へコマンドライン端末で cd して、以下の通り入力して実行してください:

java -jar VCSSL.jar
(プログラムの内容を書き変えながら使いたい場合は、代わりに VCSSL_Editor.jar を実行)

» javaコマンドが使用できない等のエラーが表示される場合は…

起動後の操作方法

まず、左のRED/GREEN/BLUE項目に、0〜255のRGB値を入力してください。または、右のCODE項目に、000000〜ffffffのカラーコードを入力してください。

続いて、

  • RGB値を入力した場合は、「 >> 」ボタンを押して下さい。
  • カラーコードを入力した場合は、「 << 」ボタンを押して下さい。

すると、画面下部の色見本ディスプレイにその色が表示され、RGB/カラーコード項目にも、入力値が相互変換されて表示されます。

題材解説

ディスプレイと色

RGB値やカラーコードは、画像処理やWEBデザイン、ソフトウェアのGUIデザインなど、幅広い分野で用いられている、色の表現方法です。

これらについて理解するためには、まずはパソコンなどのディスプレイ(モニター)が、どのようにして色を表現しているかを深く知るのが近道です。

パソコン用でもテレビでも、ディスプレイをかなり拡大して見ると、非常に小さな粒のような「画素(ピクセル)」が集まって構成されている事を確認できますが、これは赤色、緑色、青色の長方形ライトをまとめたようなものになっています。もっとも、最近の高密度なディスプレイでは肉眼で確認するのは至難の技ですが、古いテレビなどでは簡単に確認できます。

ディスプレイの画素
ディスプレイの画素

ディスプレイを拡大すると、「画素(ピクセル)」が集まって構成されています。 そして一個の画素は、光の三原色である赤色、緑色、青色の長方形ライトをまとめたようなものになっています。それぞれの色の明るさ調整する事で、画素の色が表現されます。

ディスプレイでは、この三色の長方形ライトの明るさ調整する事で、その画素の色を表現しています。液晶、プラズマ、ブラウン管といった種類は、このライトを光らせる仕組みが違うだけであって、色を表現する原理は同じです。

光の三原色と加法混色

人間の目は、どのようにして色を認識しているのでしょうか。目の仕組みを少し見てみましょう。 色覚のある生物の目には「 錐体細胞 」と言って、特定の色に反応する細胞があります。人間の持つ錐体細胞には、赤色、緑色、青色に反応する三種類が存在します(最近の研究では、どうも四種類持っている人もいるらしいですが、ここでは割愛します)。

つまり人間は、見た光に含まれている、赤色、緑色、青色の成分の比率によって、色を見分けています。なので、この三色の光を適当な比率で混ぜる事により、人間の目に対しては、ほぼ全ての色を再現できるというわけです。 それぞれの色を混ぜれば何色に見えるかは、下図の通りです。

光の三原色の混合(加法混色)
光の三原色の混合(加法混色)

赤(RED, Rと略される)、緑(GREEN, G)、青(BLUE, B)の光を適当な比率で混ぜ合わせる事で、人間の目に見える色はほぼ再現できます。 この図は、それぞれの三原色を、それぞれ一対一の比率で混合した様子です。

上図において、光の三原色を混ぜ合わせた結果の色が、絵の具の三原色を混ぜた場合と全く異なる事に、疑問を抱かれるかもしれません。その原因は、絵の具の混色と、光の混色の、メカニズムの違いによるものです。

絵の具の色は、その色以外の光を吸収し、その色だけを反射する事で、発色を行っています。なので二種類の絵の具を混ぜると、お互いの色の光を吸収しあい、共通部分の色成分だけが残ります。これを減法混色と言います。

これに対して、二色の光の混ぜ合わせでは、単純にそれぞれの光の色成分を合わせたものが、合成後の色となります。これを加法混色と呼びます。

加法混色と減法混色では、混ぜ合わせた結果の色が全く異なります。慣れるまでは注意が必要です。

24bitカラーとRGB値

ディスプレイの話に戻りましょう。現在のディスプレイで基本的なのは、「 24bitカラー 」という規格です。

24ビットカラーでは、赤色(R)、緑色(G)、青色(B)の強さを、それぞれ0〜255までの256段階で表現します。各色成分の強度を、それぞれ英語の頭文字を取って R、G、B などと呼び、まとめてRGB値と呼びます。

具体的には、純粋な青色は ( R=0, G=0, B=255 ) と表現し、純粋な黄色なら ( R=255, G=255, B=0 ) と表現します。

画素の色表現
画素の色表現

画素は、赤色(R)、緑色(G)、青色(B)の各成分の輝度を、それぞれ 0 〜 255 までの 256段階で調整し、混合して色を表現します。

それぞれの色成分の強度は、256段階なので 8bit で表現可能で、三色まとめると 24bit で表現できます。つまり一つの色を 24bit の情報量で表現するのが、24ビットカラーという事です。

カラーコード

RGB値を直接使うと、一つの色を表現するのに三つの値が必要です。しかし、一つの色を一つの数値で表現できたほうが、色々と便利な場合があります。そこで用いられるのが、カラーコードです。

カラーコードとは、6桁の16進数で表記した数値であって、一つの数値で24bitカラーの全色を表現する事ができます。

16進数とは、通常のように10で次の位に繰り上がらずに、16で初めて繰り上がるような、数字の数え方です。 慣れないと変な感じもしますが、例えば時計の秒と分は60進数と言えますし、慣れれば割と平気な数え方です。

16進数では、0〜15までを一桁に書く必要がありますが、15などはそのまま書くと二桁です。なので、10〜15 までの数は、アルファベットの a〜f で書きます。具体的には、16進数での数の数え方は:

1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f (= 10進数で15),
10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f (= 10進数で31),
20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f (= 10進数で47),
...
f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,fa,fb,fc,fd,fe,ff (= 10進数で255)

といったように数えます。ここでffは、10進数に直すと255に相当します。

つまり、2桁の16進数 00 〜 ff までで、ちょうど三原色の一つの強度を表す事が可能です。

従って、6桁用意して、頭から2桁ずつ赤色、緑色、青色を表すようにすれば、6桁の16進数 000000 〜 ffffff で、24ビットカラーの任意の色を表現する事ができます。

これが、カラーコードの規格です。なお、カラーコードは、頭に「 # 」記号を付けて記載するのが一般的です。

カラーコードの意味
カラーコードの意味

先頭から2桁ずつ、それぞれR,G,B値に対応しており、16進数で記載されています。16進数の2桁は 0〜255 までを表せるので、カラーコード一個で24bitカラーの全ての色を表現できます。

コード解説

このプログラムは VCSSLで書かれています。 ここではそのコード内容について簡単に解説します。 VCSSLはC系の単純な文法の言語なので、C言語などに触れた事のある方なら簡単に読めると思います。

コード全体

まずは、このプログラムのコード全体を掲載します。少し長いですが、以下の通りです。


coding UTF-8; // 文字化け対策

// 必要なライブラリの読み込み
import GUI;
import Math;
import Text;
import Color;
import system.Int;


// GUIのレイアウト調整用の値
const int WINDOW_WIDTH = 460;
const int WINDOW_HEIGHT = 300;
const int MARGIN = 10;
const int FIELD_WIDTH = 140;
const int FIELD_HEIGHT = 30;
const int BUTTON_WIDTH = 100;
const int BUTTON_HEIGHT = 45;
const int DISPLAY_WIDTH = WINDOW_WIDTH - 40;
const int DISPLAY_HEIGHT = WINDOW_HEIGHT - FIELD_HEIGHT*3 - 80;

// GUIコンポーネントのIDを保持する変数
int window;
int displayPanel;
int redField;
int greenField;
int blueField;
int codeField;
int rgbToCodeButton;
int codeToRgbButton;


// プログラム開始時に自動的に実行される関数
// (※ ユーザーがボタンを押した際の処理フローは、
//     ここではなくコード末尾のイベントハンドラ関数から始まります)
void main(){

	// GUIの構築
	createComponent();

	// コンソールを非表示にする
	hide();

	// 初期値のセット
	string code = "000000";
	setColorByCode(code);
}


// カラーコードを格納する文字列から色をセットする関数
void setColorByCode(string inCode){

	// CODE項目に値を設定
	setCodeField(inCode);

	// 先頭に「#」が付いていれば削除
	if(startsWith(inCode, "#")){
		inCode = cropText(inCode, 1, countText(inCode));
	}

	// 16進数のプレフィックスを付加
	inCode = "0x" + inCode;

	// 16進数として正しい表記かを検査
	if(isHex(inCode)){

		// 入力値をintに変換
		int code = inCode;

		// カラーコードとして正しい範囲内か検査
		if(0<=code && code<=0xffffff){

			// 色配列を生成
			int color[] = color(code);

			// 色見本ディスプレイに色を設定
			setDisplayColor(color);

			// RED/GREEN/BLUE項目に値を設定
			setRgbField(
				(string)color[0], (string)color[1], (string)color[2]
			);

		}else{
			alert("CODE の入力値が、#000000〜#ffffffの範囲を超えています。");
		}
	}else{
		alert("CODE の入力値が、16進数ではありません。");
	}
}


// RGB値を格納する文字列から色をセットする関数
void setColorByRgb(string inR, string inG, string inB){

	// RED/GREEN/BLUE項目に値を設定
	setRgbField(inR, inG, inB);

	// 整数として正しい表記かを検査
	if( isInt(inR) && isInt(inG) && isInt(inB) ){

		// 入力値をintに変換
		int r = inR;
		int g = inG;
		int b = inB;

		// RGB値として正しい範囲内か検査
		if(0<=r&&r<=255 && 0<=g&&g<=255 && 0<=b&&b<=255){

			// 色配列を生成
			int color[] = {r, g, b, 255};

			// 色見本ディスプレイに色を設定
			setDisplayColor(color);

			// カラーコードの取得
			string code = hex( getColorCode(color) );
			code = formatColorCode(code);

			// CODE項目に値を設定
			setCodeField(code);

		}else{
			alert("RED / GREEN / BLUE の入力値が、0〜255の範囲を超えています。");
		}

	}else{
		alert("RED / GREEN / BLUE の入力値が、整数ではありません。");
	}
}


// 16進数表記 0x〜 を、6桁のカラーコード表記に整形する関数
// (setColorByRgb 関数内で呼んでいる)
string formatColorCode(string code){

	// 文字列の初期長さを取得
    int length = countText(code);

    // 先頭の 0x を削除
    code = cropText(code, 2, length);
	length -= 2;

	// 先頭をゼロ詰めする数
	int zeros = 6 - length;

	// カラーコードは必ず6桁表記なので先頭をゼロ詰め
	for(int i=0; i<zeros; i++){
		code = "0" + code;
	}

	return code;
}





// ======================================================================
// これ以降は画面のGUIの構築処理です。
// ======================================================================

// 画面を構成するGUIコンポーネントを作成し、組み立てる関数
void createComponent(){

	// ウィンドウの作成
	window = newWindow(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, "Color Display");

	// RED/GREEN/BLUE項目パネルの作成と配置
	int rgbX = MARGIN;
	int rgbY = MARGIN;
	int rgbW = FIELD_WIDTH;
	int rgbH = FIELD_HEIGHT*3;
	int rgbPanel = createRGBPanel(rgbX, rgbY, rgbW, rgbH);
	mountComponent(rgbPanel, window);

	// ボタンパネルの作成と配置
	int bpX = rgbX + FIELD_WIDTH + MARGIN;
	int bpY = MARGIN;
	int bpW = BUTTON_WIDTH;
	int bpH = BUTTON_HEIGHT*2;
	int buttonPanel = createButtonPanel(bpX, bpY, bpW, bpH);
	mountComponent(buttonPanel, window);

	// CODE項目パネルの作成と配置
	int codeX = bpX + BUTTON_WIDTH + MARGIN;
	int codeY = MARGIN + FIELD_HEIGHT;
	int codeW = FIELD_WIDTH;
	int codeH = FIELD_HEIGHT;
	int codePanel = createCodePanel(codeX, codeY, codeW, codeH);
	mountComponent(codePanel, window);

	// 色見本ディスプレイの作成と配置
	int dpX = MARGIN;
	int dpY = rgbY + rgbH + MARGIN;
	int dpW = DISPLAY_WIDTH;
	int dpH = DISPLAY_HEIGHT;
	displayPanel = newPanel(dpX, dpY, dpW, dpH, "");
	mountComponent(displayPanel, window);
}


// RED/GREEN/BLUE項目パネルを作成する関数
int createRGBPanel(int x, int y, int width, int height){
	int panel = newGridPanel(x, y, width, height, "", 3, 2);

	// RED項目のラベルと入力欄を作成・配置
	int redLabel = newTextLabel(0, 0, 0, 0, "RED =");
	mountComponent(redLabel, panel);
	
	redField = newTextField(0, 0, 0, 0, "");
	mountComponent(redField, panel);

	// GREEN項目のラベルと入力欄を作成・配置
	int greenLabel = newTextLabel(0, 0, 0, 0, "GREEN =");
	mountComponent(greenLabel, panel);
	
	greenField = newTextField(0, 0, 0, 0, "");
	mountComponent(greenField, panel);

	// BLUE項目のラベルと入力欄を作成・配置
	int blueLabel = newTextLabel(0, 0, 0, 0, "BLUE =");
	mountComponent(blueLabel, panel);
	
	blueField = newTextField(0, 0, 0, 0, "");
	mountComponent(blueField, panel);

	return panel;
}


// CODE項目パネルを作成する関数
int createCodePanel(int x, int y, int width, int height){
	int panel = newGridPanel(x, y, width, height, "", 1, 2);
	
	int codeLabel = newTextLabel(0, 0, 0, 0, "CODE = #");
	mountComponent(codeLabel, panel);
	
	codeField = newTextField(0, 0, 0, 0, "");
	mountComponent(codeField, panel);
	
	return panel;
}


// ボタンパネルを作成する関数
int createButtonPanel(int x, int y, int width, int height){
	int panel = newGridPanel(x, y, width, height, "", 2, 1);
	
	rgbToCodeButton = newButton(0, 0, 0, 0, ">>");
	mountComponent(rgbToCodeButton, panel);
	
	codeToRgbButton = newButton(0, 0, 0, 0, "<<");
	mountComponent(codeToRgbButton, panel);
	
	return panel;
}



// ======================================================================
// これ以降は画面のGUIの更新処理です。
// ======================================================================

// 画面を構成するGUIコンポーネントを再描画する関数
void repaint(){
	paintComponent(displayPanel); // 色表示ディスプレイの第描画
	paintComponent(window);       // ウィンドウの再描画
}

// 色見本ディスプレイの色を設定する関数
void setDisplayColor(int color[]){
	int fgColor[] = {0, 0, 0, 0};                    // 前景色(パネルには作用しないので適当)
	setComponentColor(displayPanel, fgColor, color); // 色表示パネルに色を設定
	repaint();                                       // 画面を再描画
}

// RED / GREEN / BLUE項目の値を設定する関数
void setRgbField(string r, string g, string b){
	setComponentText(redField, r);   // RED項目に値を設定
	setComponentText(greenField, g); // GREEN項目に値を設定
	setComponentText(blueField, b);  // BLUE項目に値を設定
	repaint();                       // 画面を再描画
}

// CODE項目の値を設定する関数
private void setCodeField(string code){
	setComponentText(codeField, code); // CODE項目の値を設定
	repaint();                         // 画面を再描画
}



// ======================================================================
// これ以降はイベントハンドラの関数群です。
// ======================================================================

// ボタンが押された際にコールされる関数
void onButtonClick(int componentID){

	//「>>」ボタンの場合( RGB >> CODE )
	if(componentID == rgbToCodeButton){

		// RED/GREEN/BLUE項目の内容から色を設定
		string r = getComponentText(redField);
		string g = getComponentText(greenField);
		string b = getComponentText(blueField);
		setColorByRgb(r, g, b);

	//「<<」ボタンの場合( RGB << CODE )
	}else if(componentID == codeToRgbButton){

		// CODE項目の内容から色を設定
		string colorCode = getComponentText(codeField);
		setColorByCode(colorCode);
	}
}

// ウィンドウが閉じられた際にコールされる関数
void onWindowClose(int componentID){

	// メインウィンドウが閉じられたらプログラムを終了する
	if(componentID == window){
		exit();
	}
}
ColorDisplay_SJIS.vcssl

以上です。ここからは、細部を掘り下げて見ていきましょう。

先頭領域

まずは先頭からです:


coding UTF-8; // 文字化け対策

// 必要なライブラリの読み込み
import GUI;
import Math;
import Text;
import Color;
import system.Int;
import.txt

最初の行では、このプログラムのファイルで用いている文字コードが「UTF-8」である事を宣言しています。必須ではないですが、書いておくと文字化けを防げます。

※ 最近は日本語版 Windows の環境でも UTF-8 が主流になりましたが、昔に書いたスクリプトが文字化けする場合などは、ここを「coding Shift_JIS;」とすると直ったりします。昔は Shiht_JIS や CP932 が日本語での主流の文字コードだったためです。

続いて標準ライブラリから、GUIを扱う「 GUI 」と、数学関数を扱う「 Math 」、文字列の解析を行う「 Text 」、色を扱う「 Color 」を読み込んでいます。これらは、このプログラムで使う機能群を提供してくれます。

加えて、int型の使用を補助してくれる「 system.Int 」も読み込んでいます。 今回はこのライブラリを、GUIからの入力値が数字かどうか判定するのに使用します。

GUI関連の変数/定数宣言

その後は、GUIのレイアウト用の数値や、コンポーネントID(部品の管理用ID)を控える変数などを宣言しています:


// GUIのレイアウト調整用の値
const int WINDOW_WIDTH = 460;
const int WINDOW_HEIGHT = 300;
const int MARGIN = 10;
const int FIELD_WIDTH = 140;
const int FIELD_HEIGHT = 30;
const int BUTTON_WIDTH = 100;
const int BUTTON_HEIGHT = 45;
const int DISPLAY_WIDTH = WINDOW_WIDTH - 40;
const int DISPLAY_HEIGHT = WINDOW_HEIGHT - FIELD_HEIGHT*3 - 80;

// GUIコンポーネントのIDを保持する変数
int window;
int displayPanel;
int redField;
int greenField;
int blueField;
int codeField;
int rgbToCodeButton;
int codeToRgbButton;
var.txt

GUI部品に値を設定したり取得したりする際は、上で宣言されているID変数を、設定・取得用の関数に指定します。

起動時の処理など

続いて、プログラム起動時の処理などです。


// プログラム開始時に自動的に実行される関数
// (※ ユーザーがボタンを押した際の処理フローは、
//     ここではなくコード末尾のイベントハンドラ関数から始まります)
void main(){

	// GUIの構築
	createComponent();

	// コンソールを非表示にする
	hide();

	// 初期値のセット
	string code = "000000";
	setColorByCode(code);
}
system.txt

この main 関数は、グローバル領域の初期化が終わった時点で、システムから自動でコールされる関数です。実質的にはここがプログラムの実行開始地点(エントリーポイント)のようなものになります。

main関数の中では、まずcreateComponent関数を呼んで画面のGUIを構築しています。このcreateComponentもプログラム中に記述した関数ですが、ひたすらGUI部品を生成して配置する作業が続いているだけなので、詳細は割愛します。

その次は、コンソールが不要なので、システム関数の hide をコールして非表示にしています。こうするとコンソールが閉じられなくなり、そのままではプログラムを終了させる手段が無くなるので、別途メインウィンドウを閉じた時点で eixt をコールして終了するようにもしています。詳しくはonWindowCloseイベントハンドラの記述をご参照下さい。

最後に、起動時点での表示色とカラーコードを黒色(#000000)に設定しています。ここで色設定に用いている setColorByCode(...) 関数はこのスクリプト内で定義されていて、中心処理の一つです。

setColorByCode関数

それでは続けて、上で最後に登場した中心処理の一つである、setColorByCode関数の中を見ていきましょう。


// カラーコードを格納する文字列から色をセットする関数
void setColorByCode(string inCode){

	// CODE項目に値を設定
	setCodeField(inCode);

	// 先頭に「#」が付いていれば削除
	if(startsWith(inCode, "#")){
		inCode = cropText(inCode, 1, countText(inCode));
	}

	// 16進数のプレフィックスを付加
	inCode = "0x" + inCode;

	// 16進数として正しい表記かを検査
	if(isHex(inCode)){

		// 入力値をintに変換
		int code = inCode;

		// カラーコードとして正しい範囲内か検査
		if(0<=code && code<=0xffffff){

			// 色配列を生成
			int color[] = color(code);

			// 色見本ディスプレイに色を設定
			setDisplayColor(color);

			// RED/GREEN/BLUE項目に値を設定
			setRgbField(
				(string)color[0], (string)color[1], (string)color[2]
			);

		}else{
			alert("CODE の入力値が、#000000〜#ffffffの範囲を超えています。");
		}
	}else{
		alert("CODE の入力値が、16進数ではありません。");
	}
}
set_color_by_code.txt

この関数は、カラーコードを文字列で受け取って、それが表す色を設定する関数です。具体的には、その色を色見本ディスプレイ部に表示し、RGB値に変換した数値も表示します。

少し長い関数なので、頭から見ていきましょう。

最初に行っているのは入力値のテストです。 受け取ったカラーコードの先頭に「#」記号が付いていればそれを削除し、変わりにint型で16進数を表すプレフィックス「0x」を付加しています。

そしてそれが16進数として正しい内容かどうかを、system.Int ライブラリの isHex 関数でテストしています。


// CODE項目に値を設定
setCodeField(inCode);

// 先頭に「#」が付いていれば削除
if(startsWith(inCode, "#")){
	inCode = cropText(inCode, 1, countText(inCode));
}

// 16進数のプレフィックスを付加
inCode = "0x" + inCode;

// 16進数として正しい表記かを検査
if(isHex(inCode)){

	...
hex_type_test.txt

続いてさらに、入力値がカラーコードとして適切な範囲( 000000 〜 ffffff )に収まっているかをテストしています。


// 入力値をintに変換
int code = inCode;

// カラーコードとして正しい範囲内か検査
if(0<=code && code<=0xffffff){

	...
hex_range_test.txt

最後に、これらのテストをパスしてきた場合、その色を設定する処理を行っています。


// 色配列を生成
int color[] = color(code);

// 色見本ディスプレイに色を設定
setDisplayColor(color);

// RED/GREEN/BLUE項目に値を設定
setRgbField(
	(string)color[0], (string)color[1], (string)color[2]
);
hex_set.txt

ここでまず行っているのが、カラーコードからRGB値への変換です。これは独自にコードを書いても比較的簡単に実装できますが、色を扱う標準ライブラリである「 Color 」に用意されているので、それを使っています。 変換を行うのは color( int colorCode ) 関数で、この関数は引数をカラーコードと見なして解釈し、RGBA値を格納する int[4] 配列として返してくれます。 RGBAというのは、RGBに透明度(α値)を加えた規格ですが、今回はα値は使わず、RGBの値だけを使います。

続いて、取得した色を色見本ディスプレイに表示させています。これに用いている setDisplayColor 関数は、このプログラム内に実装されています。

最後に、色配列の [0], [1], [2] が R, G, B値なので、その値を画面に表示させています。これに用いている setRgbField 関数も、このプログラム内に実装されています。

setColorByRgb関数

続いて逆変換、つまり RGB値 からカラーコードへの変換処理を見て見ましょう。


// RGB値を格納する文字列から色をセットする関数
void setColorByRgb(string inR, string inG, string inB){

	// RED/GREEN/BLUE項目に値を設定
	setRgbField(inR, inG, inB);

	// 整数として正しい表記かを検査
	if( isInt(inR) && isInt(inG) && isInt(inB) ){

		// 入力値をintに変換
		int r = inR;
		int g = inG;
		int b = inB;

		// RGB値として正しい範囲内か検査
		if(0<=r&&r<=255 && 0<=g&&g<=255 && 0<=b&&b<=255){

			// 色配列を生成
			int color[] = {r, g, b, 255};

			// 色見本ディスプレイに色を設定
			setDisplayColor(color);

			// カラーコードの取得
			string code = hex( getColorCode(color) );
			code = formatColorCode(code);

			// CODE項目に値を設定
			setCodeField(code);

		}else{
			alert("RED / GREEN / BLUE の入力値が、0〜255の範囲を超えています。");
		}

	}else{
		alert("RED / GREEN / BLUE の入力値が、整数ではありません。");
	}
}
set_color_by_rgb.txt

これも最初のほうは、入力値が整数か、0〜255までの範囲にあるかなどのテストを行っています。そしてテストをパスした場合、その色を設定する作業を行っています。

テストをパスした場合の処理、つまり一番内側の if 文のブロック内を頭から見ていくと、まず、R, G, B値をまとめて色配列を作成しています。その際、最後にもう一つ、透明度を表す「α値」成分を加えています。α値は255としていますが、これは完全に不透明である事を意味します。 まず、R, G, B値をまとめて色配列を作成しています。その際、最後にもう一つ、透明度を表す「α値」成分を加えています。α値は255としていますが、これは完全に不透明である事を意味します。


                // 色配列を生成
                int color[] = {r, g, b, 255};
color_array.txt

続いて、取得した色を色見本ディスプレイに表示させています。先にも述べましたが、これに用いている setDisplayColor 関数は、このプログラム内に実装されています。

その後、色配列をカラーコードに変換しています。これも比較的簡単に実装できますが、Colorライブラリに getColorCode( int rgba[] ) として既に用意されているので、それを利用しています。 取得したカラーコードは int 型なので、Mathライブラリの hex( int value ) 関数で、16進数表記の文字列に変換しています。この際、先頭にプレフィックス「 0x 」が付加されます。


                // カラーコードの取得
                string code = hex( getColorCode(color) );
                code = formatColorCode(code);
to_color_code.txt

そして、16進数表記したカラーコードをさらに、カラーコードとして適切な形に整形しています。具体的には先頭の「 0x 」の除去と、必要に応じて先頭を「 0 」で埋めて6桁にするなどです。 これに用いている formatColorCode 関数は、この関数のすぐ後に実装されています:

formatColorCode 関数


// 16進数表記 0x〜 を、6桁のカラーコード表記に整形する関数
// (setColorByRgb 関数内で呼んでいる)
string formatColorCode(string code){

	// 文字列の初期長さを取得
    int length = countText(code);

    // 先頭の 0x を削除
    code = cropText(code, 2, length);
	length -= 2;

	// 先頭をゼロ詰めする数
	int zeros = 6 - length;

	// カラーコードは必ず6桁表記なので先頭をゼロ詰め
	for(int i=0; i<zeros; i++){
		code = "0" + code;
	}

	return code;
}
format_color_code.txt

この関数は、入力された16進数の文字列値から、まず先頭にある「0x(16進数であることを表すプレフィックス)」を取り除き、続いて6桁未満の場合にはゼロで埋めて6桁に整形します。

そして、この整形結果の値を、このスクリプト内で定義されている setCodeField(...) 関数に渡して CODE 項目に表示させています。

これで setColorByRgb(...) 関数内の処理フローが全て完結しました。まとめると、

  • 入力値の検査
  • 値の変換
  • 色の表示
  • カラーコードの整形

という処理を行った事になります。

その後は画面のGUIの構築処理がしばらく続く

さてその後は、GUI関連の処理に移っていきます。

まずは起動時に呼ばれて、画面を作ってGUI部品を生成・配置を行う createComponent() 関数と、その中で呼ばれる createRGBPanel(), createCodePanel(), createButtonPanel() 関数が続きます。


// ======================================================================
// これ以降は画面のGUIの構築処理です。
// ======================================================================

// 画面を構成するGUIコンポーネントを作成し、組み立てる関数
void createComponent(){

	// ウィンドウの作成
	window = newWindow(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, "Color Display");

	// RED/GREEN/BLUE項目パネルの作成と配置
	int rgbX = MARGIN;
	int rgbY = MARGIN;
	int rgbW = FIELD_WIDTH;
	int rgbH = FIELD_HEIGHT*3;
	int rgbPanel = createRGBPanel(rgbX, rgbY, rgbW, rgbH);
	mountComponent(rgbPanel, window);

	// ボタンパネルの作成と配置
	int bpX = rgbX + FIELD_WIDTH + MARGIN;
	int bpY = MARGIN;
	int bpW = BUTTON_WIDTH;
	int bpH = BUTTON_HEIGHT*2;
	int buttonPanel = createButtonPanel(bpX, bpY, bpW, bpH);
	mountComponent(buttonPanel, window);

	// CODE項目パネルの作成と配置
	int codeX = bpX + BUTTON_WIDTH + MARGIN;
	int codeY = MARGIN + FIELD_HEIGHT;
	int codeW = FIELD_WIDTH;
	int codeH = FIELD_HEIGHT;
	int codePanel = createCodePanel(codeX, codeY, codeW, codeH);
	mountComponent(codePanel, window);

	// 色見本ディスプレイの作成と配置
	int dpX = MARGIN;
	int dpY = rgbY + rgbH + MARGIN;
	int dpW = DISPLAY_WIDTH;
	int dpH = DISPLAY_HEIGHT;
	displayPanel = newPanel(dpX, dpY, dpW, dpH, "");
	mountComponent(displayPanel, window);
}


// RED/GREEN/BLUE項目パネルを作成する関数
int createRGBPanel(int x, int y, int width, int height){
	int panel = newGridPanel(x, y, width, height, "", 3, 2);

	// RED項目のラベルと入力欄を作成・配置
	int redLabel = newTextLabel(0, 0, 0, 0, "RED =");
	mountComponent(redLabel, panel);
	
	redField = newTextField(0, 0, 0, 0, "");
	mountComponent(redField, panel);

	// GREEN項目のラベルと入力欄を作成・配置
	int greenLabel = newTextLabel(0, 0, 0, 0, "GREEN =");
	mountComponent(greenLabel, panel);
	
	greenField = newTextField(0, 0, 0, 0, "");
	mountComponent(greenField, panel);

	// BLUE項目のラベルと入力欄を作成・配置
	int blueLabel = newTextLabel(0, 0, 0, 0, "BLUE =");
	mountComponent(blueLabel, panel);
	
	blueField = newTextField(0, 0, 0, 0, "");
	mountComponent(blueField, panel);

	return panel;
}


// CODE項目パネルを作成する関数
int createCodePanel(int x, int y, int width, int height){
	int panel = newGridPanel(x, y, width, height, "", 1, 2);
	
	int codeLabel = newTextLabel(0, 0, 0, 0, "CODE = #");
	mountComponent(codeLabel, panel);
	
	codeField = newTextField(0, 0, 0, 0, "");
	mountComponent(codeField, panel);
	
	return panel;
}


// ボタンパネルを作成する関数
int createButtonPanel(int x, int y, int width, int height){
	int panel = newGridPanel(x, y, width, height, "", 2, 1);
	
	rgbToCodeButton = newButton(0, 0, 0, 0, ">>");
	mountComponent(rgbToCodeButton, panel);
	
	codeToRgbButton = newButton(0, 0, 0, 0, "<<");
	mountComponent(codeToRgbButton, panel);
	
	return panel;
}
new_components.txt

この処理は本当にひたすらGUI部品を一個一個作っては配置していく地味な処理で、コード内コメントそのままです。 基本的には new〜関数で部品を生成してIDを取得し、位置決めをして、それを mountComponent 関数で配置する、という事を延々とくり返しています。

なお、GUIの部品生成や配置などに関する基本的な解説は、以下のガイドで解説していますので、必要に応じてそちらもご参照下さい。

GUIに関する解説はガイドで

上で掲載した通り、コード内容はある程度の長さをもっていますが、その大半はGUI(画面部品)の構築と制御に関する部分です。

このプログラムでは、GUIでは特別な事は行っておらず、基本的な処理が続いています。それらを解説しても無駄に長くなってしまうので、ここではGUI関連の解説は割愛します。

なお、GUIの構築と制御に関する基本的な内容は、以下のガイドで解説していますので、そちらをご参照下さい。

中心処理から呼ばれる、GUI更新用の関数群

その次には、画面を再描画したり、色を更新したり、RGBの表示値やカラーコードを更新したりする関数群が定義されています:


// ======================================================================
// これ以降は画面のGUIの更新処理です。
// ======================================================================

// 画面を構成するGUIコンポーネントを再描画する関数
void repaint(){
	paintComponent(displayPanel); // 色表示ディスプレイの第描画
	paintComponent(window);       // ウィンドウの再描画
}

// 色見本ディスプレイの色を設定する関数
void setDisplayColor(int color[]){
	int fgColor[] = {0, 0, 0, 0};                    // 前景色(パネルには作用しないので適当)
	setComponentColor(displayPanel, fgColor, color); // 色表示パネルに色を設定
	repaint();                                       // 画面を再描画
}

// RED / GREEN / BLUE項目の値を設定する関数
void setRgbField(string r, string g, string b){
	setComponentText(redField, r);   // RED項目に値を設定
	setComponentText(greenField, g); // GREEN項目に値を設定
	setComponentText(blueField, b);  // BLUE項目に値を設定
	repaint();                       // 画面を再描画
}

// CODE項目の値を設定する関数
private void setCodeField(string code){
	setComponentText(codeField, code); // CODE項目の値を設定
	repaint();                         // 画面を再描画
}
gui_setters.txt

これらは、序盤に登場した中心処理である setColorByCode 関数や setColorByRgb 関数の中から呼ばれて、GUIの表示更新などを行います。

ユーザーの操作に反応するイベントハンドラ

最後に、ユーザーがボタンを押したりした際に反応して、処理を行う「イベントハンドラ」の関数群です。


// ======================================================================
// これ以降はイベントハンドラの関数群です。
// ======================================================================

// ボタンが押された際にコールされる関数
void onButtonClick(int componentID){

	//「>>」ボタンの場合( RGB >> CODE )
	if(componentID == rgbToCodeButton){

		// RED/GREEN/BLUE項目の内容から色を設定
		string r = getComponentText(redField);
		string g = getComponentText(greenField);
		string b = getComponentText(blueField);
		setColorByRgb(r, g, b);

	//「<<」ボタンの場合( RGB << CODE )
	}else if(componentID == codeToRgbButton){

		// CODE項目の内容から色を設定
		string colorCode = getComponentText(codeField);
		setColorByCode(colorCode);
	}
}

// ウィンドウが閉じられた際にコールされる関数
void onWindowClose(int componentID){

	// メインウィンドウが閉じられたらプログラムを終了する
	if(componentID == window){
		exit();
	}
}
event.txt

最初の onButtonClick 関数は、ユーザーがボタンを押した際に反応するイベントハンドラで、押されたボタンのGUIコンポーネントIDが引数 componentID に渡されます。 このIDによって分岐して、ボタンに対応した処理を行っています:

  • 「<<」ボタンが押された場合: 画面からRGB値を取得して setColorByRgb(...) 関数を実行
  • 「>>」ボタンが押された場合: 画面からカラーコードを取得して setColorByCode(...) 関数を実行

setColorByRgb(...) 関数と setColorByCode(...) 関数は、このコード解説冒頭で見た通り、RGB値やカラーコードから色を生成して表示する処理でしたね。

これで、ユーザーが画面を操作してから、どういうフローでどういう処理が走って、最終的に画面に色が表示されるかが、全て繋がった事になります。

さて、最後に残る onWindowClose 関数は、ユーザーが画面を閉じた時に呼ばれるイベントハンドラです。これはもうプログラムの実行を終了させているだけです。
以上で、今回のコードは全て読み終わりました! ちょっとだけ疲れる量でしたね…

ライセンス

このVCSSL/Vnanoコード( 拡張子が「.vcssl」や「.vnano」のファイル )は実質的な著作権フリー(パブリックドメイン) である CC0 の状態で公開しています。 記事中にC言語/C++/Java言語などでのサンプルコードが掲載されいてる場合は、それらについても同様です。 そのままでのご利用はもちろん、改造や流用などもご自由に行ってください。

※ ただし、このコードの配布フォルダ内には、ダウンロード後すぐに実行できるように、 VCSSLの実行環境も同梱されており、そのライセンス文書は「 License 」フォルダ内に同梱されています (要約すると、商用・非商用問わず自由に使用できますが、使用の結果に対して開発元は一切の責任を負いません、といった具合の内容です)。 配布フォルダ内の各構成物の一覧やライセンスについては「 ReadMe_使用方法_必ずお読みください.txt 」をご参照ください。

※ Vnano の実行環境については、別途スクリプトエンジンのソースコードも一般公開しており、 何らかのソフトウェア内に組み込んでご利用いただく事も可能です。詳細はこちらをご参照ください。

この記事中の商標などについて

  • OracleとJavaは、Oracle Corporation 及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
  • Windows は、米国 Microsoft Corporation の米国およびその他の国における登録商標です。この記事は独立著作物であり、Microsoft Corporation と関連のある、もしくはスポンサーを受けるものではありません。
  • Linux は、Linus Torvalds 氏の米国およびその他の国における商標または登録商標です。
  • その他、文中に使用されている商標は、その商標を保持する各社の各国における商標または登録商標です。

Japanese English
[ 前へ | 目次 | 次へ ]
画像を任意サイズに拡大・縮小する簡易ツール(複数ファイル一括処理版)

フォルダ内にある全ての画像ファイルを開き、任意のサイズに拡大・縮小して、別のフォルダに保存する簡易ツールです。
画像を任意サイズに拡大・縮小する簡易ツール

画像ファイルを開き、任意のサイズに拡大・縮小して、別名で保存する簡易ツールです。
画像の矩形(四角形)領域を切り抜く簡易ツール(複数ファイル一括処理版)

フォルダ内にある全ての画像ファイルを開き、その中の矩形(四角形)領域を切り抜いて、別のフォルダに保存する簡易ツールです。
画像の矩形(四角形)領域を切り抜く簡易ツール

画像ファイルを開き、その中の矩形(四角形)領域を切り抜いて保存する簡易ツールです。
連番画像をアニメーション再生する簡易ツール

フォルダ内の連番画像ファイルを、動画への変換不要で、そのままアニメーションとして再生できる簡易ツールです。
条件を満たす色を透明にする簡易ツール(複数ファイル一括処理版)

フォルダ内の全画像ファイルに対して、条件を満たす範囲の色を透明に置き換え、別のフォルダに保存する簡易ツールです。
特定の色を透明にする簡易ツール(複数ファイル一括処理版)

フォルダ内にある全てのPNG形式画像ファイルを開き、特定の色を透明に置き換えた上で、別のフォルダに保存する簡易ツールです。
条件を満たす色を透明にする簡易ツール

画像ファイルを開き、指定された条件を満たす色を透明に置き換えて保存する簡易ツールです。
特定の色を透明にする簡易ツール

画像ファイルを開き、特定の色を透明に置き換えて保存する簡易ツールです。
2DCGと3DCGの合成

2DCGと3DCGを一枚に合成し、画面に表示するプログラムの例です。
RGBやカラーコードの色表示と相互変換ができる簡易ツール

RGB値とカラーコードから、GUI画面上で色の表示や相互変換を行う事ができる簡易ツールです。
頂点配列によるモデルの変形アニメーション

頂点配列によってモデルを変形アニメーションさせるサンプルです。
頂点配列によるモデルの作成(四角形格子メッシュ形式)

四角形格子メッシュの形式で、頂点配列からモデルを作成するサンプルです。
この階層の目次
[ 前へ | 目次 | 次へ ]
RINEARN からのお知らせ
※ VCSSL は RINEARN が開発しています。

各ソフトやVCSSLの英語版ドキュメント整備がほぼ完了
2025-06-30 - RINEARNでは2年前から、AIの補助による英語版ドキュメントの大幅拡充計画を進めてきました。今回、主要ドキュメント&コンテンツの英訳がほぼ完了し、一応の目標水準に達しました。詳細をお知らせします。

VCSSLの最新版をリリース: 外部プログラムとの連携機能を少し強化、他
2025-05-25 - VCSSL 3.4.52をリリースしました。外部プログラム(C言語製の実行ファイル等)との連携機能を少し強化し、文字化け対策やOS判別などを可能にしました。他にも細かい機能追加があります。詳細をお知らせします。

VCSSLの最新版をリリース、Java 24上での非互換な挙動を対処
2025-04-22 - VCSSL 3.4.50をリリースしました。Java 24環境上でのネットワークドライブ関連のファイルパス解決で、従来環境とは異なる挙動が生じていたのを解消しました。詳細をお知らせします。

リニアングラフやVCSSLの最新版をリリース、目盛りの位置や内容を自由に指定可能に!
2024-11-24 - リニアングラフ3D/2Dを更新し、自由な位置に、自由な表記内容の目盛りを描けるようになりました! 併せて、Java言語やVCSSLでの、プログラム制御用APIも拡張しています。詳細をお知らせします。

Exevalator 2.2 をリリース、TypeScript 対応によりWebブラウザ上で動作可能に
2024-10-22 - オープンソースの式計算ライブラリ「Exevalator(エグゼバレータ)」の2.1をリリースしました。新たに TypeScript に対応し、Webブラウザ上での式計算にも使えるようになりました。詳細を解説します。

アシスタントAI作成の舞台裏(その2、作成編)
2024-10-12 - アシスタントAIの作成方法解説の後編です。実際にChatGPTの「GPTs」機能を用いて、アシスタントAIを作成する手順や、独自の知識をもたせたり、精度を出すためのノウハウなどを解説しています。

アシスタントAI作成の舞台裏(その1、基礎知識編)
2024-10-07 - アシスタントAI作成方法解説の前編です。今回はまず、アシスタントAIを作る前に抑えておきたい、基礎知識を延々と解説しています。そもそもLLM型AIとはどんな存在か? RAGとは何か? 等々です。

ソフトの利用をサポートしてくれるアシスタントAIを提供開始!
2024-09-20 - RINEARN製ソフトの使い方の質問応答や、一部作業のお手伝いをしてくれる、アシスタントAIを提供開始しました。ChatGPTアカウントさえあれば、誰でも無料で使用できます。使い方を解説します。

Exevalator 2.1 をリリース、新たに Visual Basic に対応
2024-07-28 - オープンソースの式計算ライブラリ「Exevalator(エグゼバレータ)」の2.1をリリースしました。今回から、新たに Visual Basic(VB.NET)でも使用できるようになりました。詳細を解説します。

関数電卓 RINPn(りんぷん)、Esc キーで計算式の一発クリアが可能に
2024-07-20 - 関数電 RINPn の Ver.1.0.2 をリリースしました。今回から、キーボードの「 Esc 」キーを押すと、入力中の計算式を一発でクリアできるようになりました。詳細を解説します。