Skip to content

Instantly share code, notes, and snippets.

@hirosof
Created October 16, 2012 10:08
Show Gist options
  • Select an option

  • Save hirosof/3898469 to your computer and use it in GitHub Desktop.

Select an option

Save hirosof/3898469 to your computer and use it in GitHub Desktop.
#include "HSCOLOR.h"
#ifndef __HS_MYCOLOR__
#define __HS_MYCOLOR__
/*************************************************************************
関数名 :max3
機能 :3つの実数値より最大の値を返す
定義 :double max3(double num1,double num2,double num3);
書式 :maxnum = max3(num1,num2,num3);
戻り値 :渡された値のうち最大の値
パラメータ説明
maxnum・・・戻り値の代入先(実数型)
num1、num2、num3 ・・・ 比較したい実数3つ
*************************************************************************/
double max3(double num1,double num2,double num3){
double n;
n = (num1 > num2) ? num1 : num2 ;
return (n > num3) ? n : num3;
}
/*************************************************************************
関数名 :min3
機能 :3つの実数値より最小の値を返す
定義 :double min3(double num1,double num2,double num3);
書式 :minnum = min3(num1,num2,num3);
戻り値 :渡された値のうち最小の値
パラメータ説明
minnum・・・戻り値の代入先(実数型)
num1、num2、num3 ・・・ 比較したい実数3つ
*************************************************************************/
double min3(double num1,double num2,double num3){
double n;
n = (num1 < num2) ? num1 : num2 ;
return (n < num3) ? n : num3;
}
/*************************************************************************
関数名 :RGBtoHSV(別名:RGBtoHSB)
機能 :RGB値をHSV値に変換する
定義 :int RGBtoHSV(int R,int G,int B,double *H,double *S,double *V);
書式 :RGBtoHSV(R,G,B,&H,&S,&V);
戻り値 :0・・・出力パラメータに異常あり 、1・・・異常なし
入力パラメータ説明
R・・・RGB値のR(赤)の値(値の範囲:0~255)
G・・・RGB値のG(緑)の値(値の範囲:0~255)
B・・・RGB値のB(青)の値(値の範囲:0~255)
出力パラメータ説明
H・・・変換したHSV値のH値(色相)の代入先へのポインタ(値の範囲:0.0~359.9)
S・・・変換したHSV値のS値(彩度)の代入先へのポインタ(値の範囲:0.0~1.0)
V・・・変換したHSV値のV値(明度)の代入先へのポインタ(値の範囲:0.0~1.0)
*************************************************************************/
int RGBtoHSV(int R,int G,int B,double *H,double *S,double *V){
double rgb[]={R,G,B},hsv[3];
double minval,maxval;
if((!H) || (!S) || (!V))return 0;
for(int cnt=0;cnt<3;cnt++){
rgb[cnt]/=255.0; //RGBの値を0.0~1.0の間にする
//Debug用printf
//printf("rgb[%d]=%f(%d)\n",cnt,rgb[cnt],(int)(rgb[cnt]*255.0));
}
/*
最小値と最大値を取得
*/
minval = min3(rgb[0],rgb[1],rgb[2]);
maxval = max3(rgb[0],rgb[1],rgb[2]);
/*
最大値 = Vの値
*/
hsv[2] = maxval;
//Debug用printf
//printf("\nhsv[2]=%f\n",hsv[2]);
/*
Hの値を計算
*/
if(minval == maxval){
//最小値と最大値が等しい場合Hは定義されない。
hsv[0]=0.0;
}else{
//Rが最大の時60×(G-B)÷(最大値-最小値)+0
if(maxval==rgb[0])hsv[0]=60.0*(rgb[1]-rgb[2])/(maxval-minval);
//Gが最大の時60×(B-R)÷(最大値-最小値)+120
else if(maxval==rgb[1])hsv[0]=60.0*(rgb[2]-rgb[0])/(maxval-minval)+120;
//Bが最大の時60×(R-G)÷(最大値-最小値)+240
else hsv[0]=60.0*(rgb[0]-rgb[1])/(maxval-minval)+240;
//上の計算でマイナス値になった場合360.0を加算
if(hsv[0] <0)hsv[0]+=360.0;
}
//Debug用printf
//printf("hsv[0]=%f\n",hsv[0]);
/*
Sの値を計算
*/
if(maxval==0)hsv[1]=0;//最大値が0の場合Sは未定義
else hsv[1]=(maxval-minval)/maxval;
//Debug用printf
//printf("hsv[1]=%f\n",hsv[1]);
/*
結果を代入
*/
*H=hsv[0]; *S=hsv[1]; *V=hsv[2];
return 1;
}
/*************************************************************************
関数名 :HSVtoRGB(別名:HSBtoRGB)
機能 :HSV値をRGB値に変換する
定義 :int HSVtoRGB(double H,double S,double V,int *R,int *G,int *B);
書式 :HSVtoRGB(H,S,V,&R,&G,&B);
戻り値 :0・・・出力パラメータに異常あり 、1・・・異常なし
入力パラメータ説明
H・・・HSV値のH値(色相、値の範囲:0.0~359.9)
S・・・HSV値のS値(彩度、値の範囲:0.0~1.0)
V・・・HSV値のV値(明度、値の範囲:0.0~1.0)
出力パラメータ説明
R・・・RGB値のR値(赤)の代入先へのポインタ(値の範囲:0~255)
G・・・RGB値のG値(緑)の代入先へのポインタ(値の範囲:0~255)
B・・・RGB値のB値(青)の代入先へのポインタ(値の範囲:0~255)
*************************************************************************/
int HSVtoRGB(double H,double S,double V,int *R,int *G,int *B){
int hi;
double f,p,q,t,fr,fg,fb;
if((!R) || (!G) || (!B))return 0;
if(S==0){
*R = *G = *B = (int)(float)(V*255);
return 1;
}
hi=((int)(H/60.0))%6;
//printf("hi=%d\n",hi);
f=H/60.0-hi;
//printf("f=%f\n",f);
p = V * (1 - S);
//printf("p=%f\n",p);
q = V * (1 - f*S);
//printf("q=%f\n",q);
t = V * (1 - (1 - f)*S);
//printf("t=%f\n",t);
switch(hi){
case 0:
fr = V ; fg = t ; fb = p;
break;
case 1:
fr = q ; fg = V ; fb = p;
break;
case 2:
fr = p ; fg = V ; fb = t;
break;
case 3:
fr = p ; fg = q ; fb = V;
break;
case 4:
fr = t ; fg = p ; fb = V;
break;
case 5:
fr = V ; fg = p ; fb = q;
break;
}
/*
結果を0.0~1.00 -> 0~255に変換して代入
*/
*R =(int)(float)(fr * 255);
*G =(int)(float)(fg * 255);
*B =(int)(float)(fb * 255);
return 0;
}
/*************************************************************************
関数名 :RGBtoHLS(別名:RGBtoHSL 及び RGBtoHSI)
機能 :RGB値をHLS値に変換する
定義 :int RGBtoHLS(int R,int G,int B,double *H,double *L,double *S);
書式 :RGBtoHLS(R,G,B,&H,&L,&S);
戻り値 :0・・・出力パラメータに異常あり 、1・・・異常なし
入力パラメータ説明
R・・・RGB値のR(赤)の値(値の範囲:0~255)
G・・・RGB値のG(緑)の値(値の範囲:0~255)
B・・・RGB値のB(青)の値(値の範囲:0~255)
出力パラメータ説明
H・・・変換したHLS値のH値(色相)の代入先へのポインタ(値の範囲:0.0~359.9)
L・・・変換したHLS値のL値(輝度)の代入先へのポインタ(値の範囲:0.0~1.0)
S・・・変換したHLS値のS値(彩度)の代入先へのポインタ(値の範囲:0.0~1.0)
*************************************************************************/
int RGBtoHLS(int R , int G , int B , double *H , double *L , double *S){
double valRGB[] = { R , G , B } , valHLS[3]={ 0 , 0 , 0 };
double maxNum = 0 , minNum=0;
if((!H)||(!L)||(!S))return 0;
//0~255の範囲であるRGB値を0.0~1.0の範囲にする
for(int cnt=0 ; cnt < 3 ; cnt++){
valRGB[cnt]/=255;
//printf("rgb[%d]=%f(%d)\n",cnt,valRGB[cnt],(int)(valRGB[cnt]*255.0));
}
//最小値と最大値を取得
maxNum = max3(valRGB[0],valRGB[1],valRGB[2]);
minNum = min3(valRGB[0],valRGB[1],valRGB[2]);
//printf("maxNum = %.2f minNum = %.2f\n",maxNum,minNum);
//L=(最大値 + 最小値)/2
valHLS[1] =(maxNum + minNum)/2;
//SとHの値を取得
if(maxNum == minNum){
//最大値 = 最小値の時 HとSはともに0である;
valHLS[0] = valHLS[2] = 0;
}else{
/*
Sを計算
*/
//L≦0.5の時 S = (最大値 - 最小値)/(最大値 + 最小値)
if(valHLS[1]<=0.5)valHLS[2] = (maxNum - minNum)/(maxNum + minNum);
//L>0.5の時 S = (最大値 - 最小値)/(2 - 最大値 - 最小値)
else valHLS[2] = (maxNum - minNum)/(2 - maxNum - minNum);
/*
Hを計算(計算式はHSVのHと同じ)
*/
//Rが最大の時60×(G-B)÷(最大値-最小値)+0
if(maxNum==valRGB[0])valHLS[0]=60.0*(valRGB[1]-valRGB[2])/(maxNum-minNum);
//Gが最大の時60×(B-R)÷(最大値-最小値)+120
else if(maxNum==valRGB[1])valHLS[0]=60.0*(valRGB[2]-valRGB[0])/(maxNum-minNum)+120;
//Bが最大の時60×(R-G)÷(最大値-最小値)+240
else valHLS[0]=60.0*(valRGB[0]-valRGB[1])/(maxNum-minNum)+240;
//上の計算でマイナス値になった場合360.0を加算
if(valHLS[0] <0)valHLS[0]+=360.0;
}
/*
*H , *L , *Sに代入
*/
*H = valHLS[0] ; *L = valHLS[1] ; *S = valHLS[2];
return 1;
}
/*************************************************************************
関数名 :HLStoRGB(別名:HSLtoRGB 及び HSItoRGB)
機能 :HLS値をRGB値に変換する
定義 :int HLStoRGB(double H,double L,double S,int *R,int *G,int *B);
書式 :HLStoRGB(H,L,S,&R,&G,&B);
戻り値 :0・・・出力パラメータに異常あり 、1・・・異常なし
入力パラメータ説明
H・・・HSV値のH値(色相、値の範囲:0.0~359.9)
S・・・HSV値のL値(輝度、値の範囲:0.0~1.0)
V・・・HSV値のS値(彩度、値の範囲:0.0~1.0)
出力パラメータ説明
R・・・RGB値のR値(赤)の代入先へのポインタ(値の範囲:0~255)
G・・・RGB値のG値(緑)の代入先へのポインタ(値の範囲:0~255)
B・・・RGB値のB値(青)の代入先へのポインタ(値の範囲:0~255)
*************************************************************************/
int HLStoRGB(double H,double L,double S,int *R,int *G,int *B){
double valRGB[3]={0,0,0},valH,nMax,nMin;
if((!R) || (!G) || (!B))return 0;
if(S==0){
//S=0 の時 R = G = B = L
//但し範囲は 0.0~1.0なので
//範囲を0~255になるように255倍して代入
*R = *G = *B = (int)(float)(L * 255);
return 1;
}else{
nMax = (L <=0.5) ? L*(1 + S) : L*(1 - S) + S ;
nMin = 2*L - nMax;
//Rの値を計算
valH = H + 120;
if(valH >= 360)valH -= 360;
if((valH >= 0) && (valH < 60)){
valRGB[0] = nMin + (nMax - nMin) * valH / 60;
}else if((valH >= 60) && (valH<180)){
valRGB[0] = nMax;
}else if((valH >= 180) && (valH<240)){
valRGB[0] = nMin + (nMax - nMin)*(240 - valH) / 60;
}else{
valRGB[0] = nMin;
}
//Gの値を計算
valH = H;
if((valH >= 0) && (valH < 60)){
valRGB[1] = nMin + (nMax - nMin) * valH / 60;
}else if((valH >= 60) && (valH<180)){
valRGB[1] = nMax;
}else if((valH >= 180) && (valH<240)){
valRGB[1] = nMin + (nMax - nMin)*(240 - valH) / 60;
}else{
valRGB[1] = nMin;
}
//Bの値を計算
valH = H - 120;
if(valH < 0)valH += 360;
if((valH >= 0) && (valH < 60)){
valRGB[2] = nMin + (nMax - nMin) * valH / 60;
}else if((valH >= 60) && (valH<180)){
valRGB[2] = nMax;
}else if((valH >= 180) && (valH<240)){
valRGB[2] = nMin + (nMax - nMin)*(240 - valH) / 60;
}else{
valRGB[2] = nMin;
}
}
//RGB値を0~255になるように変換して代入
for(int cnt=0 ; cnt < 3 ; cnt++)valRGB[cnt] *=255;
*R = (int)(float)valRGB[0];
*G = (int)(float)valRGB[1];
*B = (int)(float)valRGB[2];
return 1;
}
#endif /*__HS_MYCOLOR__*/
//プロトタイプ宣言
#ifndef __HS_MYCOLOR_H__
#define __HS_MYCOLOR_H__
//マクロ登録
//各関数の別名マクロ
//RGB HSV
#define RGBtoHSB RGBtoHSV
#define HSBtoRGB HSVtoRGB
//RGB HSL
#define RGBtoHSL RGBtoHLS
#define HSLtoRGB HLStoRGB
#define RGBtoHSI RGBtoHLS
#define HSItoRGB HLStoRGB
//プロトタイプ宣言
double max3(double,double,double);
double min3(double,double,double);
int RGBtoHSV(int ,int ,int ,double*,double*,double*);
int HSVtoRGB(double,double,double,int* ,int* ,int*);
int RGBtoHLS(int ,int ,int ,double*,double*,double*);
int HLStoRGB(double,double,double,int* ,int* ,int*);
#endif /* __HS_MYCOLOR_H__ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment