HSV2RGB and RGB2HSV
HSV.cpp@1:a06dfdf279e2, 2015-10-02 (annotated)
- Committer:
- JackB
- Date:
- Fri Oct 02 22:29:47 2015 +0000
- Revision:
- 1:a06dfdf279e2
- Parent:
- 0:e3c23a157dee
Adafruit 64x32 RGB LED Matrix - 3mm pitch Demo program for Nucleo F446RE.; Use User button to display color palette in second framebuffer.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JackB | 0:e3c23a157dee | 1 | /* mbed HSV Library |
JackB | 0:e3c23a157dee | 2 | * |
JackB | 0:e3c23a157dee | 3 | * Copyright (c) 2013-2013 JackB, cstyles |
JackB | 0:e3c23a157dee | 4 | * |
JackB | 0:e3c23a157dee | 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
JackB | 0:e3c23a157dee | 6 | * of this software and associated documentation files (the "Software"), to deal |
JackB | 0:e3c23a157dee | 7 | * in the Software without restriction, including without limitation the rights |
JackB | 0:e3c23a157dee | 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
JackB | 0:e3c23a157dee | 9 | * copies of the Software, and to permit persons to whom the Software is |
JackB | 0:e3c23a157dee | 10 | * furnished to do so, subject to the following conditions: |
JackB | 0:e3c23a157dee | 11 | * |
JackB | 0:e3c23a157dee | 12 | * The above copyright notice and this permission notice shall be included in |
JackB | 0:e3c23a157dee | 13 | * all copies or substantial portions of the Software. |
JackB | 0:e3c23a157dee | 14 | * |
JackB | 0:e3c23a157dee | 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
JackB | 0:e3c23a157dee | 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
JackB | 0:e3c23a157dee | 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
JackB | 0:e3c23a157dee | 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
JackB | 0:e3c23a157dee | 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
JackB | 0:e3c23a157dee | 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
JackB | 0:e3c23a157dee | 21 | * THE SOFTWARE. |
JackB | 0:e3c23a157dee | 22 | */ |
JackB | 0:e3c23a157dee | 23 | |
JackB | 0:e3c23a157dee | 24 | #include "HSV.h" |
JackB | 0:e3c23a157dee | 25 | |
JackB | 0:e3c23a157dee | 26 | HSV::HSV() { |
JackB | 0:e3c23a157dee | 27 | Rgb.Out = 4095.0; |
JackB | 0:e3c23a157dee | 28 | SetRcf(1.0); |
JackB | 0:e3c23a157dee | 29 | SetGcf(1.0); |
JackB | 0:e3c23a157dee | 30 | SetBcf(1.0); |
JackB | 0:e3c23a157dee | 31 | SetWcf(1.0); |
JackB | 0:e3c23a157dee | 32 | SetH(0.0); // Hue |
JackB | 0:e3c23a157dee | 33 | SetS(1.0); // Saturation |
JackB | 0:e3c23a157dee | 34 | SetV(1.0); // Value |
JackB | 0:e3c23a157dee | 35 | SetP(1.0); // Power |
JackB | 0:e3c23a157dee | 36 | SetPower(true); |
JackB | 0:e3c23a157dee | 37 | } |
JackB | 0:e3c23a157dee | 38 | |
JackB | 0:e3c23a157dee | 39 | void HSV::SetPower(bool Power) |
JackB | 0:e3c23a157dee | 40 | { |
JackB | 0:e3c23a157dee | 41 | _Power = Power; |
JackB | 0:e3c23a157dee | 42 | } |
JackB | 0:e3c23a157dee | 43 | |
JackB | 0:e3c23a157dee | 44 | |
JackB | 0:e3c23a157dee | 45 | int HSV::UseWeb(char* String) |
JackB | 0:e3c23a157dee | 46 | { |
JackB | 0:e3c23a157dee | 47 | // #c08040 |
JackB | 0:e3c23a157dee | 48 | char Str[3]; |
JackB | 0:e3c23a157dee | 49 | Str[2] = '\0'; |
JackB | 0:e3c23a157dee | 50 | Str[0] = String[1]; |
JackB | 0:e3c23a157dee | 51 | Str[1] = String[2]; |
JackB | 0:e3c23a157dee | 52 | int R = (int)strtol(Str, NULL, 16); |
JackB | 0:e3c23a157dee | 53 | Str[0] = String[3]; |
JackB | 0:e3c23a157dee | 54 | Str[1] = String[4]; |
JackB | 0:e3c23a157dee | 55 | int G = (int)strtol(Str, NULL, 16); |
JackB | 0:e3c23a157dee | 56 | Str[0] = String[5]; |
JackB | 0:e3c23a157dee | 57 | Str[1] = String[6]; |
JackB | 0:e3c23a157dee | 58 | int B = (int)strtol(Str, NULL, 16); |
JackB | 0:e3c23a157dee | 59 | return (int)(((R & 0xf8) << 8) + ((G & 0xfc) << 3) + ((B & 0xf8) >> 3)); |
JackB | 0:e3c23a157dee | 60 | } |
JackB | 0:e3c23a157dee | 61 | |
JackB | 0:e3c23a157dee | 62 | int HSV::UseRGB(int R, int G, int B) |
JackB | 0:e3c23a157dee | 63 | { |
JackB | 0:e3c23a157dee | 64 | return (int)(((R & 0xf8) << 8) + ((G & 0xfc) << 3) + ((B & 0xf8) >> 3)); |
JackB | 0:e3c23a157dee | 65 | } |
JackB | 0:e3c23a157dee | 66 | |
JackB | 0:e3c23a157dee | 67 | int HSV::UseHSV(float H, float S, float V) |
JackB | 0:e3c23a157dee | 68 | { |
JackB | 0:e3c23a157dee | 69 | Hsv.H = H; |
JackB | 0:e3c23a157dee | 70 | Hsv.S = S; |
JackB | 0:e3c23a157dee | 71 | Hsv.V = V; |
JackB | 0:e3c23a157dee | 72 | HSV_to_RGB(); |
JackB | 0:e3c23a157dee | 73 | int R = (int) (sqrt(Rgb.R) * (float)255.0); |
JackB | 0:e3c23a157dee | 74 | int G = (int) (sqrt(Rgb.G) * (float)255.0); |
JackB | 0:e3c23a157dee | 75 | int B = (int) (sqrt(Rgb.B) * (float)255.0); |
JackB | 0:e3c23a157dee | 76 | return (int)(((R & 0xf8) << 8) + ((G & 0xfc) << 3) + ((B & 0xf8) >> 3)); |
JackB | 0:e3c23a157dee | 77 | } |
JackB | 0:e3c23a157dee | 78 | |
JackB | 0:e3c23a157dee | 79 | void HSV::SetRcf(float Rcf) |
JackB | 0:e3c23a157dee | 80 | { |
JackB | 0:e3c23a157dee | 81 | Rgb.Rcf = Rcf; |
JackB | 0:e3c23a157dee | 82 | HSV_to_RGB(); |
JackB | 0:e3c23a157dee | 83 | // RGB_to_HSV(); |
JackB | 0:e3c23a157dee | 84 | } |
JackB | 0:e3c23a157dee | 85 | |
JackB | 0:e3c23a157dee | 86 | void HSV::SetGcf(float Gcf) |
JackB | 0:e3c23a157dee | 87 | { |
JackB | 0:e3c23a157dee | 88 | Rgb.Gcf = Gcf; |
JackB | 0:e3c23a157dee | 89 | HSV_to_RGB(); |
JackB | 0:e3c23a157dee | 90 | // RGB_to_HSV(); |
JackB | 0:e3c23a157dee | 91 | } |
JackB | 0:e3c23a157dee | 92 | |
JackB | 0:e3c23a157dee | 93 | void HSV::SetBcf(float Bcf) |
JackB | 0:e3c23a157dee | 94 | { |
JackB | 0:e3c23a157dee | 95 | Rgb.Bcf = Bcf; |
JackB | 0:e3c23a157dee | 96 | HSV_to_RGB(); |
JackB | 0:e3c23a157dee | 97 | // RGB_to_HSV(); |
JackB | 0:e3c23a157dee | 98 | } |
JackB | 0:e3c23a157dee | 99 | |
JackB | 0:e3c23a157dee | 100 | void HSV::SetWcf(float Wcf) |
JackB | 0:e3c23a157dee | 101 | { |
JackB | 0:e3c23a157dee | 102 | Rgb.Wcf = Wcf; |
JackB | 0:e3c23a157dee | 103 | HSV_to_RGB(); |
JackB | 0:e3c23a157dee | 104 | // RGB_to_HSV(); |
JackB | 0:e3c23a157dee | 105 | } |
JackB | 0:e3c23a157dee | 106 | |
JackB | 0:e3c23a157dee | 107 | void HSV::SetH(float Hue) |
JackB | 0:e3c23a157dee | 108 | { |
JackB | 0:e3c23a157dee | 109 | Hsv.H = Hue; |
JackB | 0:e3c23a157dee | 110 | HSV_to_RGB(); |
JackB | 0:e3c23a157dee | 111 | // RGB_to_HSV(); |
JackB | 0:e3c23a157dee | 112 | } |
JackB | 0:e3c23a157dee | 113 | |
JackB | 0:e3c23a157dee | 114 | void HSV::SetS(float Saturation) |
JackB | 0:e3c23a157dee | 115 | { |
JackB | 0:e3c23a157dee | 116 | Hsv.S = Saturation; |
JackB | 0:e3c23a157dee | 117 | HSV_to_RGB(); |
JackB | 0:e3c23a157dee | 118 | // RGB_to_HSV(); |
JackB | 0:e3c23a157dee | 119 | } |
JackB | 0:e3c23a157dee | 120 | |
JackB | 0:e3c23a157dee | 121 | void HSV::SetV(float Value) |
JackB | 0:e3c23a157dee | 122 | { |
JackB | 1:a06dfdf279e2 | 123 | Hsv.V = Value; |
JackB | 1:a06dfdf279e2 | 124 | HSV_to_RGB(); |
JackB | 1:a06dfdf279e2 | 125 | // RGB_to_HSV(); |
JackB | 1:a06dfdf279e2 | 126 | } |
JackB | 1:a06dfdf279e2 | 127 | |
JackB | 1:a06dfdf279e2 | 128 | void HSV::SetVV(float Value) |
JackB | 1:a06dfdf279e2 | 129 | { |
JackB | 0:e3c23a157dee | 130 | Hsv.V = Value * Value; |
JackB | 0:e3c23a157dee | 131 | HSV_to_RGB(); |
JackB | 0:e3c23a157dee | 132 | // RGB_to_HSV(); |
JackB | 0:e3c23a157dee | 133 | } |
JackB | 0:e3c23a157dee | 134 | |
JackB | 0:e3c23a157dee | 135 | void HSV::SetP(float Value) |
JackB | 0:e3c23a157dee | 136 | { |
JackB | 0:e3c23a157dee | 137 | Hsv.P = Value; |
JackB | 0:e3c23a157dee | 138 | HSV_to_RGB(); |
JackB | 0:e3c23a157dee | 139 | // RGB_to_HSV(); |
JackB | 0:e3c23a157dee | 140 | } |
JackB | 0:e3c23a157dee | 141 | |
JackB | 0:e3c23a157dee | 142 | void HSV::SetW(float White) |
JackB | 0:e3c23a157dee | 143 | { |
JackB | 0:e3c23a157dee | 144 | Rgb.W = White; |
JackB | 0:e3c23a157dee | 145 | } |
JackB | 0:e3c23a157dee | 146 | |
JackB | 0:e3c23a157dee | 147 | uint16_t HSV::GetRout(void) |
JackB | 0:e3c23a157dee | 148 | { |
JackB | 0:e3c23a157dee | 149 | if (_Power) |
JackB | 0:e3c23a157dee | 150 | return (uint16_t)(Rgb.R * Rgb.Rcf * Rgb.Out); |
JackB | 0:e3c23a157dee | 151 | return 0; |
JackB | 0:e3c23a157dee | 152 | } |
JackB | 0:e3c23a157dee | 153 | |
JackB | 0:e3c23a157dee | 154 | uint16_t HSV::GetGout(void) |
JackB | 0:e3c23a157dee | 155 | { |
JackB | 0:e3c23a157dee | 156 | if (_Power) |
JackB | 0:e3c23a157dee | 157 | return (uint16_t)(Rgb.G * Rgb.Gcf * Rgb.Out); |
JackB | 0:e3c23a157dee | 158 | return 0; |
JackB | 0:e3c23a157dee | 159 | } |
JackB | 0:e3c23a157dee | 160 | |
JackB | 0:e3c23a157dee | 161 | uint16_t HSV::GetBout(void) |
JackB | 0:e3c23a157dee | 162 | { |
JackB | 0:e3c23a157dee | 163 | if (_Power) |
JackB | 0:e3c23a157dee | 164 | return (uint16_t)(Rgb.B * Rgb.Bcf * Rgb.Out); |
JackB | 0:e3c23a157dee | 165 | return 0; |
JackB | 0:e3c23a157dee | 166 | } |
JackB | 0:e3c23a157dee | 167 | |
JackB | 0:e3c23a157dee | 168 | uint16_t HSV::GetWout(void) |
JackB | 0:e3c23a157dee | 169 | { |
JackB | 0:e3c23a157dee | 170 | if (_Power) |
JackB | 0:e3c23a157dee | 171 | return (uint16_t)(Rgb.W * Rgb.Wcf * Rgb.Out); |
JackB | 0:e3c23a157dee | 172 | return 0; |
JackB | 0:e3c23a157dee | 173 | } |
JackB | 0:e3c23a157dee | 174 | |
JackB | 0:e3c23a157dee | 175 | float HSV::GetR(void) |
JackB | 0:e3c23a157dee | 176 | { |
JackB | 0:e3c23a157dee | 177 | return Rgb.R; |
JackB | 0:e3c23a157dee | 178 | } |
JackB | 0:e3c23a157dee | 179 | |
JackB | 0:e3c23a157dee | 180 | float HSV::GetG(void) |
JackB | 0:e3c23a157dee | 181 | { |
JackB | 0:e3c23a157dee | 182 | return Rgb.G; |
JackB | 0:e3c23a157dee | 183 | } |
JackB | 0:e3c23a157dee | 184 | |
JackB | 0:e3c23a157dee | 185 | float HSV::GetB(void) |
JackB | 0:e3c23a157dee | 186 | { |
JackB | 0:e3c23a157dee | 187 | return Rgb.B; |
JackB | 0:e3c23a157dee | 188 | } |
JackB | 0:e3c23a157dee | 189 | |
JackB | 0:e3c23a157dee | 190 | float HSV::GetW(void) |
JackB | 0:e3c23a157dee | 191 | { |
JackB | 0:e3c23a157dee | 192 | return Rgb.W; |
JackB | 0:e3c23a157dee | 193 | } |
JackB | 0:e3c23a157dee | 194 | |
JackB | 0:e3c23a157dee | 195 | float HSV::GetH(void) |
JackB | 0:e3c23a157dee | 196 | { |
JackB | 0:e3c23a157dee | 197 | return Hsv.H; |
JackB | 0:e3c23a157dee | 198 | } |
JackB | 0:e3c23a157dee | 199 | |
JackB | 0:e3c23a157dee | 200 | float HSV::GetS(void) |
JackB | 0:e3c23a157dee | 201 | { |
JackB | 0:e3c23a157dee | 202 | return Hsv.S; |
JackB | 0:e3c23a157dee | 203 | } |
JackB | 0:e3c23a157dee | 204 | |
JackB | 0:e3c23a157dee | 205 | float HSV::GetV(void) |
JackB | 0:e3c23a157dee | 206 | { |
JackB | 0:e3c23a157dee | 207 | return Hsv.V; |
JackB | 0:e3c23a157dee | 208 | } |
JackB | 0:e3c23a157dee | 209 | |
JackB | 0:e3c23a157dee | 210 | float HSV::GetH2(void) |
JackB | 0:e3c23a157dee | 211 | { |
JackB | 0:e3c23a157dee | 212 | return Hsv2.H; |
JackB | 0:e3c23a157dee | 213 | } |
JackB | 0:e3c23a157dee | 214 | |
JackB | 0:e3c23a157dee | 215 | float HSV::GetS2(void) |
JackB | 0:e3c23a157dee | 216 | { |
JackB | 0:e3c23a157dee | 217 | return Hsv2.S; |
JackB | 0:e3c23a157dee | 218 | } |
JackB | 0:e3c23a157dee | 219 | |
JackB | 0:e3c23a157dee | 220 | float HSV::GetV2(void) |
JackB | 0:e3c23a157dee | 221 | { |
JackB | 0:e3c23a157dee | 222 | return Hsv2.V; |
JackB | 0:e3c23a157dee | 223 | } |
JackB | 0:e3c23a157dee | 224 | |
JackB | 0:e3c23a157dee | 225 | void HSV::HSV_to_RGB(void) |
JackB | 0:e3c23a157dee | 226 | { |
JackB | 0:e3c23a157dee | 227 | // H is given on [0, 6] or UNDEFINED. S and V are given on [0, 1]. |
JackB | 0:e3c23a157dee | 228 | // RGB are each returned on [0, 1]. |
JackB | 0:e3c23a157dee | 229 | Rgb.W = ((float)1.0 - Hsv.S) * Hsv.V * Hsv.P; |
JackB | 0:e3c23a157dee | 230 | while (Hsv.H < (float)0.0) |
JackB | 0:e3c23a157dee | 231 | Hsv.H += (float)1.0; |
JackB | 0:e3c23a157dee | 232 | while (Hsv.H >= (float)1.0) |
JackB | 0:e3c23a157dee | 233 | Hsv.H -= (float)1.0; |
JackB | 0:e3c23a157dee | 234 | float h_div = (float)1.0 / (float)6.0; |
JackB | 0:e3c23a157dee | 235 | float h = Hsv.H/h_div; |
JackB | 0:e3c23a157dee | 236 | float s = Hsv.S; |
JackB | 0:e3c23a157dee | 237 | float v = Hsv.V * Hsv.P; |
JackB | 0:e3c23a157dee | 238 | float m, n, f; |
JackB | 0:e3c23a157dee | 239 | int i = floor(h); |
JackB | 0:e3c23a157dee | 240 | f = h - (float) i; |
JackB | 0:e3c23a157dee | 241 | if ( !(i&1) ) |
JackB | 0:e3c23a157dee | 242 | f = 1 - f; // if i is even |
JackB | 0:e3c23a157dee | 243 | m = v * (1 - s); |
JackB | 0:e3c23a157dee | 244 | n = v * (1 - s * f); |
JackB | 0:e3c23a157dee | 245 | switch (i) { |
JackB | 0:e3c23a157dee | 246 | case 0 : Rgb.R = v; Rgb.G = n; Rgb.B = m; break; |
JackB | 0:e3c23a157dee | 247 | case 1 : Rgb.R = n; Rgb.G = v; Rgb.B = m; break; |
JackB | 0:e3c23a157dee | 248 | case 2 : Rgb.R = m; Rgb.G = v; Rgb.B = n; break; |
JackB | 0:e3c23a157dee | 249 | case 3 : Rgb.R = m; Rgb.G = n; Rgb.B = v; break; |
JackB | 0:e3c23a157dee | 250 | case 4 : Rgb.R = n; Rgb.G = m; Rgb.B = v; break; |
JackB | 0:e3c23a157dee | 251 | case 5 : Rgb.R = v; Rgb.G = m; Rgb.B = n; break; |
JackB | 0:e3c23a157dee | 252 | default : Rgb.R = v; Rgb.G = n; Rgb.B = m; break; |
JackB | 0:e3c23a157dee | 253 | } |
JackB | 0:e3c23a157dee | 254 | } |
JackB | 0:e3c23a157dee | 255 | |
JackB | 0:e3c23a157dee | 256 | void HSV::RGB_to_HSV(void) |
JackB | 0:e3c23a157dee | 257 | { |
JackB | 0:e3c23a157dee | 258 | float rgbMin, rgbMax; |
JackB | 0:e3c23a157dee | 259 | |
JackB | 0:e3c23a157dee | 260 | rgbMin = Rgb.R < Rgb.G ? (Rgb.R < Rgb.B ? Rgb.R : Rgb.B) : (Rgb.G < Rgb.B ? Rgb.G : Rgb.B); |
JackB | 0:e3c23a157dee | 261 | rgbMax = Rgb.R > Rgb.G ? (Rgb.R > Rgb.B ? Rgb.R : Rgb.B) : (Rgb.G > Rgb.B ? Rgb.G : Rgb.B); |
JackB | 0:e3c23a157dee | 262 | |
JackB | 0:e3c23a157dee | 263 | Hsv2.V = rgbMax; |
JackB | 0:e3c23a157dee | 264 | if (Hsv2.V == 0.0) |
JackB | 0:e3c23a157dee | 265 | { |
JackB | 0:e3c23a157dee | 266 | Hsv2.H = 0.0; |
JackB | 0:e3c23a157dee | 267 | Hsv2.S = 0.0; |
JackB | 0:e3c23a157dee | 268 | return; |
JackB | 0:e3c23a157dee | 269 | } |
JackB | 0:e3c23a157dee | 270 | |
JackB | 0:e3c23a157dee | 271 | Hsv2.S = (rgbMax - rgbMin) / Hsv2.V; |
JackB | 0:e3c23a157dee | 272 | if (Hsv2.S == 0.0) |
JackB | 0:e3c23a157dee | 273 | { |
JackB | 0:e3c23a157dee | 274 | Hsv2.H = 0.0; |
JackB | 0:e3c23a157dee | 275 | return; |
JackB | 0:e3c23a157dee | 276 | } |
JackB | 0:e3c23a157dee | 277 | |
JackB | 0:e3c23a157dee | 278 | if (rgbMax == Rgb.R) |
JackB | 0:e3c23a157dee | 279 | Hsv2.H = 1.0/6.0 * (Rgb.G - Rgb.B) / (rgbMax - rgbMin); |
JackB | 0:e3c23a157dee | 280 | else if (rgbMax == Rgb.G) |
JackB | 0:e3c23a157dee | 281 | Hsv2.H = 1.0/3.0 + 1.0/6.0 * (Rgb.B - Rgb.R) / (rgbMax - rgbMin); |
JackB | 0:e3c23a157dee | 282 | else |
JackB | 0:e3c23a157dee | 283 | Hsv2.H = 2.0/3.0 + 1.0/6.0 * (Rgb.R - Rgb.G) / (rgbMax - rgbMin); |
JackB | 0:e3c23a157dee | 284 | } |
JackB | 0:e3c23a157dee | 285 |