001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 *  image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause 
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 
006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 
007 * Visit http://imagingbook.com for additional details.
008 *******************************************************************************/
009package imagingbook.pub.color.image;
010
011/**
012 * Methods for converting between RGB and HLS color spaces.
013 * @author W. Burger
014 * @version 2013-12-25
015*/
016public class HsvConverter {
017
018        public float[] RGBtoHSV (int[] RGB) {
019                int R = RGB[0], G = RGB[1], B = RGB[2]; // R,G,B in [0,255]
020                int cHi = Math.max(R,Math.max(G,B));    // highest color value
021                int cLo = Math.min(R,Math.min(G,B));    // lowest color value
022                int cRng = cHi - cLo;                               // component range
023                float H = 0, S = 0, V = 0;
024                float cMax = 255.0f;
025
026                // compute value V
027                V = cHi / cMax;
028                
029                // compute saturation S
030                if (cHi > 0)
031                        S = (float) cRng / cHi;
032
033                // compute hue H
034                if (cRng > 0) { // hue is defined only for color pixels
035                        float rr = (float)(cHi - R) / cRng;
036                        float gg = (float)(cHi - G) / cRng;
037                        float bb = (float)(cHi - B) / cRng;
038                        float hh;
039                        if (R == cHi)                   // r is greatest component value
040                                hh = bb - gg;
041                        else if (G == cHi)              // g is greatest component value
042                                hh = rr - bb + 2;
043                        else                            // b is greatest component value
044                                hh = gg - rr + 4;
045                        if (hh < 0)
046                                hh = hh + 6;
047                        H = hh / 6;
048                }
049                return new float[] {H, S, V};
050        }
051        
052        public int[] HSVtoRGB (float[] HSV) {
053                float H = HSV[0], S = HSV[1], V = HSV[2];  // h,s,v in [0,1]
054                float r = 0, g = 0, b = 0;
055                float hh = (6 * H) % 6;                 
056                int   c1 = (int) hh;                     
057                float c2 = hh - c1;
058                float x = (1 - S) * V;
059                float y = (1 - (S * c2)) * V;
060                float z = (1 - (S * (1 - c2))) * V;     
061                switch (c1) {
062                        case 0: r = V; g = z; b = x; break;
063                        case 1: r = y; g = V; b = x; break;
064                        case 2: r = x; g = V; b = z; break;
065                        case 3: r = x; g = y; b = V; break;
066                        case 4: r = z; g = x; b = V; break;
067                        case 5: r = V; g = x; b = y; break;
068                }       
069                int R = Math.min((int)(r * 255), 255);
070                int G = Math.min((int)(g * 255), 255);
071                int B = Math.min((int)(b * 255), 255);
072                return new int[] {R, G, B};
073        }
074
075}