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}