> DXライブラリ内関数の
> unsigned int GetColor( int Red , int Green , int Blue ) ;
> で得られるカラーコードはHTMLとかで使う16新数で表すカラーコードとは互換性はありますか?
GetColor の戻り値を 16進数表示すると HTML の16進数のカラーコードのような表示になりますが、
互換性はありません
> GetColor関数を使ったある特定の色から色相だけを順番に変えていくにはどうすればいいでしょうか?
GetColor で得られる色値は GetColor2 という関数で R, G, B に分解することができますので、
R, G, B の値を色相・明度・彩度の値に変換して、色相の値のみを変更し、今度は色相・輝度・彩度の
値を R, G, B の値に変換したあと、GetColor で色値に戻せば色相だけを順番に変えていくことができます
R, G, B の値と 色相・輝度・彩度 を相互変換する関数はDXライブラリには無いので、
R, G, B の値を 色相・輝度・彩度 に変換したり、逆に 色相・輝度・彩度 の値を R, G, B に
変換する関数を含んだサンプルコードを作成してみました
よろしければご覧ください
#include "DxLib.h"
// RGBカラーからHLSカラーに変換( H:0〜0x5ff L:0〜255 s:0〜255 )
extern int RGBToHLS( int R, int G, int B, int *H, int *L, int *S )
{
int h, l, s, c, min, max ;
// 最小値と最大値を得る
max = R >= G ? ( R >= B ? R : B ) : ( G >= B ? G : B ) ;
min = R <= G ? ( R <= B ? R : B ) : ( G <= B ? G : B ) ;
// 最大値と最小値の差を得る
c = max - min ;
// 初期チェック
if( R == 0 && G == 0 && B == 0 )
{
h = 0 ;
l = 0 ;
s = 0 ;
}
else
if( R == 255 && G == 255 && B == 255 )
{
h = 0 ;
l = 255 ;
s = 0 ;
}
else
if( R == G && G == B )
{
h = 0 ;
l = R ;
s = 0 ;
}
else
{
// 色相を得る
{
int r, g, b, mx ;
r = R - min ;
g = G - min ;
b = B - min ;
mx = r >= g ? ( r >= b ? r : b ) : ( g >= b ? g : b ) ;
r = ( r << 8 ) / mx ;
g = ( g << 8 ) / mx ;
b = ( b << 8 ) / mx ;
if( r == 0x100 )
{
if( b == 0 )
{
h = 0 + g ;
}
else
{
h = 0x600 - b ;
}
}
else
if( g == 0x100 )
{
if( r == 0 )
{
h = 0x200 + b ;
}
else
{
h = 0x200 - r ;
}
}
else
if( b == 0x100 )
{
if( g == 0 )
{
h = 0x400 + r ;
}
else
{
h = 0x400 - g ;
}
}
}
// 輝度を求める
{
l = ( min + max ) >> 1 ;
}
// 彩度を求める
{
int w ;
w = ( l >= 0x80 ? ( 0xff - l ) << 1 : l << 1 ) + 1 ;
s = ( c * 255 ) / w ;
}
}
if( H != NULL ) *H = h ;
if( L != NULL ) *L = l ;
if( S != NULL ) *S = s ;
// 終了
return 0 ;
}
// HLSカラーからRGBカラーに変換( H:0〜0x5ff L:0〜255 s:0〜255 )
extern int HLSToRGB( int H, int L, int S, int *R, int *G, int *B )
{
int r, g, b ;
if( L == 0 )
{
g = b = r = 0 ;
}
else
if( L == 255 )
{
r = g = b = 255 ;
}
else
{
// 色相選択処理
H = H % 0x600 ;
if( H >= 0 && H < 0x100 )
{
r = 0xff ;
g = H ;
b = 0 ;
}
else
if( H >= 0x100 && H < 0x200 )
{
r = 0x1ff - H ;
g = 0xff ;
b = 0 ;
}
else
if( H >= 0x200 && H < 0x300 )
{
r = 0 ;
g = 0xff ;
b = H - 0x200 ;
}
else
if( H >= 0x300 && H < 0x400 )
{
r = 0 ;
g = 0x3ff - H ; b = 0xff ;
}
else
if( H >= 0x400 && H < 0x500 )
{
r = H - 0x400 ;
g = 0 ;
b = 0xff ;
}
else
if( H >= 0x500 && H < 0x600 )
{
r = 0xff ;
g = 0 ;
b = 0x5ff - H ;
}
// 彩度と輝度の計算を行う
{
// 彩度が加わる
r += ( 0x80 - r ) * ( 0xff - S ) / 0xff ;
g += ( 0x80 - g ) * ( 0xff - S ) / 0xff ;
b += ( 0x80 - b ) * ( 0xff - S ) / 0xff ;
// 輝度が加わる
if( L <= 0x80 )
{
r = ( r * ( L << 1 ) ) >> 8 ;
g = ( g * ( L << 1 ) ) >> 8 ;
b = ( b * ( L << 1 ) ) >> 8 ;
}
else
{
r += ( 0xff - r ) * ( ( L - 0x80 ) << 1 ) / 0xff ;
g += ( 0xff - g ) * ( ( L - 0x80 ) << 1 ) / 0xff ;
b += ( 0xff - b ) * ( ( L - 0x80 ) << 1 ) / 0xff ;
}
}
}
// 代入
if( R ) *R = r ;
if( G ) *G = g ;
if( B ) *B = b ;
// 終了
return 0 ;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int Color ;
int R, G, B ;
int H, L, S ;
int HAddNum ;
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1 ;
// 描画先を裏画面にする
SetDrawScreen( DX_SCREEN_BACK ) ;
// メインループ
HAddNum = 0 ;
while( ProcessMessage() == 0 )
{
// 画面のクリア
ClearDrawScreen() ;
// 色相を変化させる割合の値をインクリメント
HAddNum ++ ;
// GetColor で明るい赤色の色値を取得
Color = GetColor( 255, 80, 80 ) ;
// 色値を R, G, B の値に分解
GetColor2( Color, &R, &G, &B ) ;
// R, G, B, の値を色相(H), 輝度(L), 彩度(S) に変換
RGBToHLS( R, G, B, &H, &L, &S ) ;
// 色相(H) に変化を与えた値で、R, G, B に変換
HLSToRGB( ( H + HAddNum ) % 0x600, L, S, &R, &G, &B ) ;
// 得られた R, G, B の値で四角形を描画
DrawBox( 100, 100, 300, 300, GetColor( R, G, B ), TRUE ) ;
// 裏画面の内容を表画面に反映
ScreenFlip() ;
}
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}
> 明度は真ん中?で彩度は最大で色相だけ順番に変える方法です。
上記のサンプルプログラムの
// 色相(H) に変化を与えた値で、R, G, B に変換
HLSToRGB( ( H + HAddNum ) % 0x600, L, S, &R, &G, &B ) ;
この HLTToRGB 関数呼び出しの第二、第三引数をそれぞれ
128, 255 にすると明度が真ん中、彩度が最大になります