トップ 戻るハッカーと画家 コンピュータ時代の創造者たち

ColorRGBToHLS-HSL色空間の利用

最近のペイントの色作成などで使用するカラーダイアログでは、おなじみの赤緑青での指定に加え「色合い/鮮やかさ/明るさ」で色を指定することもできます。この方式は、どうやら「HSL」という色と明るさを分離した色の指定方式(色空間)のようで、シェル関連APIにはRGBとHSLを相互に変換するAPIも用意されています。
このHSLは、明るさと色が分離され、また色に関しても「色合い」「鮮やかさ」といった感覚的な操作ができるので、なかなか便利です。今回は、BMPを32ビットDIBに読み込んでその画像のRGBを一度HSLに変換、各ピクセルのHSLに対し処理を行いまたRGBに戻す、という方式で、HSLで遊んでみることにしました。

RGBとHSLの相互変換

HSLは、色合い(H)、鮮やかさ(S)、明るさ(L)を0-240(Hは0-239)の数値で表します。RGBとの関係はなかなか複雑ですが、APIを使えば簡単に変換できるので、とりあえず遊んでみるだけなら気にしないでよいでしょう(^^;。気になる方は、MSDN(比較的新しいVC++のドキュメントやオンラインのMSDNサイト)でHSLまたはHLS(ドキュメントやAPIの名前には、HSLとHLSが混在しています)で検索すれば、変換処理の具体的な内容を見ることができます。

このHSLとおなじみのRGBの変換ですが、APIで行う場合はColorRGBToHLS()/ColorHLSToRGB()を呼び出すだけです。ただ、RGBといっても、RGBとしてやり取りするのはCOLORREF(ビット列としてはBGR)なので、32ビットDIBのピクセル列をそのまま渡すことはできません。RとB(32ビット中の17-24、1-8ビット目)を入れ替える必要があります。

ColorRGBToHLS

ColorRGBToHLS(COLORREF clSrc, WORD *lpH, WORD *lpL, WORD *lpS);

clSrcで指定されたCOLORREFの色をHSLに変換し、その結果をlpH/lpL/lpSが示すアドレスに格納します。

ColorHLSToRGB

ColorHLSToRGB(WORD wH, WORD wL, WORD wS);

wH/wL/wSで指定されるHSLからCOLORREFを求め、その値を返します。

使い方は、特に難しくないですね。ただ、32ビットDIBのピクセル値(RGB)とCOLORREFとの間でも変換が必要になるのがやや面倒ですが。
今回は、以下のような関数を作ってRGBとCOLORREFを変換しています。

RGB-COLORREF変換関数
/* 下位24ビットのうち、1-8ビット目と17-24ビット目を入れ替える */
DWORD RGBcvCOLORREF(DWORD dwSrc) {

	DWORD dw3 = (dwSrc & 0x00ff0000) >> 16;
	DWORD dw2 = dwSrc & 0x0000f000;
	DWORD dw1 = (dwSrc & 0x000000ff) << 16;

	return dw1 | dw2 | dw3;

}

実際の変換処理は、32ビットDIBピクセル列g_lpdwPixelに対して、以下のように行います。

DIBピクセル列のHSL処理
for (int i = 0;i < g_iHeight;i++) {
	for (int j = 0;j < g_iWidth; j++) {

		/* (j, i)のRGBをHSLに変換 */
		ColorRGBToHLS(RGBcvCOLORREF(g_lpdwPixel[j + i * g_iWidth]),
		              &wH, &wL, &wS);

		/* HSLをいじって遊ぶ */

		/* 処理したHSLをRGBに戻してピクセルに設定 */
		g_lpdwPixel[j + i * g_iWidth] = RGBcvCOLORREF(ColorHLSToRGB(wH, wL, wS));

	}
}

プログラム

プログラムを起動したら、ウインドウに適当な24ビットフルカラーBMPをドロップしてください。その後実行ボタンをクリックすると、func()の処理が実行され結果が表示されます。
あとは、func()内で行っている処理をいろいろ変えて遊んでみましょう。色合いを変えたい時は、Hを、彩度を変えたい時はSを、明るさを変えたい時はLをいじります。

ただ、Lをいじっていると、どうも真っ黒になる部分が出てきたりするようですね。また、変換のたびに誤差が出てくるはずですから、何度も処理を繰り返すときには注意が必要です。

なお、このColorRGBToHLS()/ColorHLSToRGB()を使うには、WindowsXP(デフォルトの2000/MEも可?)やIE5がインストールされた環境が必要です。また、ライブラリやインクルードファイルが必要なので、古い開発環境だとプログラムのビルドができないかもしれません。その場合は最近のSDKをインストールするなり、自分でdllからAPIを読み込んで使うなりしてください。

プログラムソース表示 プログラムダウンロード


トップ 戻るシーザム (防犯・護身用品専門店)