1818 * XYZ -> CIE-LAB -> XYZ
1919 * @author Diego Catalano
2020 */
21+
22+
2123public class ColorConverter {
2224
2325 /**
@@ -26,6 +28,7 @@ public class ColorConverter {
2628 private ColorConverter () {}
2729
2830 public static enum YCbCrColorSpace {ITU_BT_601 ,ITU_BT_709_HDTV };
31+ private final static double EPSILON = 0.00001 ;
2932
3033 // XYZ (Tristimulus) Reference values of a perfect reflecting diffuser
3134
@@ -259,7 +262,7 @@ public static int[] YCbCrtoRGB(float y, float cb, float cr, YCbCrColorSpace colo
259262 * @param blue Blue coefficient.
260263 * @return Normalized RGChromaticity. Range[0..1].
261264 */
262- public static double [] RGChromaticity (int red , int green , int blue ){
265+ public static float [] RGChromaticity (int red , int green , int blue ){
263266 double [] color = new double [5 ];
264267
265268 double sum = red + green + blue ;
@@ -276,24 +279,7 @@ public static double[] RGChromaticity(int red, int green, int blue){
276279 double rS = color [0 ] - 0.333 ;
277280 double gS = color [1 ] - 0.333 ;
278281
279- //saturation
280- color [3 ] = Math .sqrt (rS * rS + gS * gS );
281-
282- //hue
283- color [4 ] = Math .atan (rS / gS );
284-
285- return color ;
286- }
287-
288- /**
289- * RGB -> HSV.
290- * Adds (hue + 360) % 360 for represent hue in the range [0..359].
291- * @param red Red coefficient. Values in the range [0..255].
292- * @param green Green coefficient. Values in the range [0..255].
293- * @param blue Blue coefficient. Values in the range [0..255].
294- * @return HSV color space.
295- */
296- public static float [] RGBtoHSV (int red , int green , int blue ){
282+ //saturationBRGBtoHSV(int red, int green, int blue){
297283 float [] hsv = new float [3 ];
298284 float r = red / 255f ;
299285 float g = green / 255f ;
@@ -630,69 +616,69 @@ public static float[] RGBtoHunterLAB(int red, int green, int blue){
630616 public static int [] HunterLABtoRGB (float l , float a , float b ){
631617 float [] xyz = HunterLABtoXYZ (l , a , b );
632618 return XYZtoRGB (xyz [0 ], xyz [1 ], xyz [2 ]);
633- }
619+ }
634620
635621 /**
636- * RGB -> HLS .
622+ * RGB -> HSL .
637623 * @param red Red coefficient. Values in the range [0..255].
638624 * @param green Green coefficient. Values in the range [0..255].
639625 * @param blue Blue coefficient. Values in the range [0..255].
640- * @return HLS color space.
626+ * @return HSL color space.
641627 */
642- public static float [] RGBtoHLS (int red , int green , int blue ){
628+ public static float [] RGBtoHSL (int red , int green , int blue ){
643629 float [] hsl = new float [3 ];
644630
645- float r = red / 255f ;
646- float g = green / 255f ;
647- float b = blue / 255f ;
631+ double r = red ;
632+ double g = green ;
633+ double b = blue ;
648634
649- float max = Math .max (r ,Math .max (r ,b ));
650- float min = Math .min (r ,Math .min (r ,b ));
651- float delta = max - min ;
635+ double max = Math .max (r ,Math .max (g ,b ));
636+ double min = Math .min (r ,Math .min (g ,b ));
637+ // double delta = max - min;
652638
653639 //HSK
654- float h = 0 ;
655- float s = 0 ;
656- float l = (max + min ) / 2 ;
657-
658- if ( delta == 0 ){
659- // gray color
660- h = 0 ;
661- s = 0.0f ;
662- }
663- else
664- {
665- // get saturation value
666- s = ( l <= 0.5 ) ? ( delta / ( max + min ) ) : ( delta / ( 2 - max - min ) );
667-
668- // get hue value
669- float hue ;
670-
671- if ( r == max )
672- {
673- hue = ( ( g - b ) / 6 ) / delta ;
640+ Double h = 0d ;
641+ Double s = 0d ;
642+ Double l = 0d ;
643+
644+ //saturation
645+ double cnt = (max + min ) / 2d ;
646+ if (cnt <= 127d ) {
647+ s = ((max - min ) / (max + min ));
674648 }
675- else if ( g == max )
676- {
677- hue = ( 1.0f / 3 ) + ( ( b - r ) / 6 ) / delta ;
649+ else {
650+ s = ((max - min ) / (510d - max - min ));
678651 }
679- else
680- {
681- hue = ( 2.0f / 3 ) + ( ( r - g ) / 6 ) / delta ;
652+
653+ //lightness
654+ l = ((max + min ) / 2d ) / 255d ;
655+
656+ //hue
657+ if (Math .abs (max - min ) <= EPSILON ) {
658+ h = 0d ;
659+ s = 0d ;
682660 }
661+ else {
662+ double diff = max - min ;
683663
684- // correct hue if needed
685- if ( hue < 0 )
686- hue += 1 ;
687- if ( hue > 1 )
688- hue -= 1 ;
664+ if (Math .abs (max - r ) <= EPSILON ) {
665+ h = 60d * (g - b ) / diff ;
666+ }
667+ else if (Math .abs (max - g ) <= EPSILON ) {
668+ h = 60d * (b - r ) / diff + 120d ;
669+ }
670+ else {
671+ h = 60d * (r - g ) / diff + 240d ;
672+ }
689673
690- h = (int ) ( hue * 360 );
691- }
674+ if (h < 0d ) {
675+ h += 360d ;
676+ }
677+ }
692678
693- hsl [0 ] = h ;
694- hsl [1 ] = s ;
695- hsl [2 ] = l ;
679+ hsl [0 ] = h . floatValue () ;
680+ hsl [1 ] = s . floatValue () ;
681+ hsl [2 ] = l . floatValue () ;
696682
697683 return hsl ;
698684 }
@@ -931,14 +917,19 @@ public static XYColorSpace XYZtoXY(float x, float y, float z){
931917 */
932918 public static float [] XYtoXYZ (XYColorSpace xy ){
933919 float [] xyz = new float [3 ];
934-
920+ /* Old Way
935921 xyz[0] = (xy.getBrightnessAdjusted() / xy.getXy()[1]) * xy.getXy()[0];
936922 xyz[1] = xy.getBrightnessAdjusted();
937923 xyz[2] = (xy.getBrightnessAdjusted() / xy.getXy()[1]) * (1.0f - xy.getXy()[0] - xy.getXy()[1]);
938-
924+ */
925+ // New Way
926+ xyz [0 ] = xy .getXy ()[0 ] * (xy .getBrightnessAdjusted () / xy .getXy ()[1 ]) ;
927+ xyz [1 ] = xy .getBrightnessAdjusted ();
928+ xyz [2 ] = (float ) ((1.0 - xy .getXy ()[0 ] - xy .getXy ()[1 ]) * (xy .getBrightnessAdjusted () / xy .getXy ()[1 ]));
929+
939930 return xyz ;
940931 }
941-
932+
942933 public static int [] normalizeRGB (int [] rgb ) {
943934 int [] newRGB = new int [3 ];
944935
0 commit comments