inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_colormanip 00005 #define inlib_colormanip 00006 00007 namespace inlib { 00008 00009 // rgbs are ints in [0,255] 00010 // h in [0,360], h -1 problem. 00011 // s in [0,255] 00012 // v in [0,255] 00013 00014 // red (255, 0, 0) is hsv (0,255,255) 00015 // green (0, 255, 0) is hsv (120,255,255) 00016 // blue (0, 0,255) is hsv (240,255,255) 00017 // white (255,255,255) is hsv (-1,0,255) 00018 // black (0, 0, 0) is hsv (-1,0,0) 00019 00020 00021 // From QColor. 00022 inline void rgb2hsv(int r,int g,int b, int& h, int& s, int& v ) { 00023 00024 unsigned int mx = r; // mximum RGB component 00025 int whatmx = 0; // r=>0, g=>1, b=>2 00026 if ( (unsigned int)g > mx ) { 00027 mx = g; 00028 whatmx = 1; 00029 } 00030 if ( (unsigned int)b > mx ) { 00031 mx = b; 00032 whatmx = 2; 00033 } 00034 unsigned int mn = r; // find mnimum value 00035 if ( (unsigned int)g < mn ) mn = g; 00036 if ( (unsigned int)b < mn ) mn = b; 00037 int delta = mx-mn; 00038 v = mx; // calc value 00039 s = mx ? (510*delta+mx)/(2*mx) : 0; 00040 if ( s == 0 ) { 00041 h = -1; // undefined hue 00042 } else { 00043 switch ( whatmx ) { 00044 case 0: // red is mx component 00045 if ( g >= b ) 00046 h = (120*(g-b)+delta)/(2*delta); 00047 else 00048 h = (120*(g-b+delta)+delta)/(2*delta) + 300; 00049 break; 00050 case 1: // green is mx component 00051 if ( b > r ) 00052 h = 120 + (120*(b-r)+delta)/(2*delta); 00053 else 00054 h = 60 + (120*(b-r+delta)+delta)/(2*delta); 00055 break; 00056 case 2: // blue is mx component 00057 if ( r > g ) 00058 h = 240 + (120*(r-g)+delta)/(2*delta); 00059 else 00060 h = 180 + (120*(r-g+delta)+delta)/(2*delta); 00061 break; 00062 } 00063 } 00064 } 00065 00066 inline bool hsv2rgb( int h, int s, int v ,int& r,int& g, int& b) { 00067 if ( h < -1 || (unsigned int)s > 255 || (unsigned int)v > 255 ) { 00068 r = g = b = 0; 00069 return false; 00070 } 00071 r=v; 00072 g=v; 00073 b=v; 00074 if ( s == 0 || h == -1 ) { // achromatic case 00075 // Ignore 00076 } else { // chromatic case 00077 if ( (unsigned int)h >= 360 ) h %= 360; 00078 unsigned int f = h%60; 00079 h /= 60; 00080 unsigned int p = (unsigned int)(2*v*(255-s)+255)/510; 00081 unsigned int q, t; 00082 if ( h&1 ) { 00083 q = (unsigned int)(2*v*(15300-s*f)+15300)/30600; 00084 switch( h ) { 00085 case 1: r=(int)q; g=(int)v, b=(int)p; break; 00086 case 3: r=(int)p; g=(int)q, b=(int)v; break; 00087 case 5: r=(int)v; g=(int)p, b=(int)q; break; 00088 } 00089 } else { 00090 t = (unsigned int)(2*v*(15300-(s*(60-f)))+15300)/30600; 00091 switch( h ) { 00092 case 0: r=(int)v; g=(int)t, b=(int)p; break; 00093 case 2: r=(int)p; g=(int)v, b=(int)t; break; 00094 case 4: r=(int)t; g=(int)p, b=(int)v; break; 00095 } 00096 } 00097 } 00098 return true; 00099 } 00100 00101 } 00102 00103 #endif