diff --git a/src/lv_misc/lv_color.c b/src/lv_misc/lv_color.c index f5bec62bb7..cd4825dfe5 100644 --- a/src/lv_misc/lv_color.c +++ b/src/lv_misc/lv_color.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ #include "lv_color.h" +#include "lv_math.h" /********************* * DEFINES @@ -105,39 +106,66 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v) } /** - * Convert an RGB color to HSV - * @param r red - * @param g green - * @param b blue - * @return the given RGB color n HSV + * Convert a 32-bit RGB color to HSV + * @param r8 8-bit red + * @param g8 8-bit green + * @param b8 8-bit blue + * @return the given RGB color in HSV */ -lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b) +lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8) { + uint16_t r = ((uint32_t)r8 << 10) / 255; + uint16_t g = ((uint32_t)g8 << 10) / 255; + uint16_t b = ((uint32_t)b8 << 10) / 255; + + uint16_t rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b); + uint16_t rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b); + lv_color_hsv_t hsv; - uint8_t rgbMin, rgbMax; - rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b); - rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b); + // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness + hsv.v = (100 * rgbMax) >> 10; - hsv.v = rgbMax; - if(hsv.v == 0) { + int32_t delta = rgbMax - rgbMin; + if (LV_MATH_ABS(delta) < 3) { hsv.h = 0; hsv.s = 0; return hsv; } - hsv.s = 255 * (long)(rgbMax - rgbMin) / hsv.v; - if(hsv.s == 0) { + // https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation + hsv.s = 100 * delta / rgbMax; + if(hsv.s < 3) { hsv.h = 0; return hsv; } + // https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma + int32_t h; if(rgbMax == r) - hsv.h = 0 + 43 * (g - b) / (rgbMax - rgbMin); + h = (((g - b) << 10) / delta) + (g < b ? (6 << 10) : 0); // between yellow & magenta else if(rgbMax == g) - hsv.h = 85 + 43 * (b - r) / (rgbMax - rgbMin); + h = (((b - r) << 10) / delta) + (2 << 10); // between cyan & yellow + else if(rgbMax == b) + h = (((r - g) << 10) / delta) + (4 << 10); // between magenta & cyan else - hsv.h = 171 + 43 * (r - g) / (rgbMax - rgbMin); + h = 0; + h *= 60; + h >>= 10; + if (h < 0) h += 360; + hsv.h = h; return hsv; } + +/** + * Convert a color to HSV + * @param color color + * @return the given color in HSV + */ +lv_color_hsv_t lv_color_to_hsv(lv_color_t color) +{ + lv_color32_t color32; + color32.full = lv_color_to32(color); + return lv_color_rgb_to_hsv(color32.ch.red, color32.ch.green, color32.ch.blue); +} diff --git a/src/lv_misc/lv_color.h b/src/lv_misc/lv_color.h index f2aadccaa8..04551fe7f4 100644 --- a/src/lv_misc/lv_color.h +++ b/src/lv_misc/lv_color.h @@ -466,13 +466,20 @@ static inline lv_color_t lv_color_hex3(uint32_t c) lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v); /** - * Convert an RGB color to HSV - * @param r red - * @param g green - * @param b blue - * @return the given RGB color n HSV + * Convert a 32-bit RGB color to HSV + * @param r8 8-bit red + * @param g8 8-bit green + * @param b8 8-bit blue + * @return the given RGB color in HSV */ -lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b); +lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8); + +/** + * Convert a color to HSV + * @param color color + * @return the given color in HSV + */ +lv_color_hsv_t lv_color_to_hsv(lv_color_t color); /********************** * MACROS diff --git a/src/lv_misc/lv_log.c b/src/lv_misc/lv_log.c index 2d12da4e1b..acbdfb7327 100644 --- a/src/lv_misc/lv_log.c +++ b/src/lv_misc/lv_log.c @@ -12,6 +12,7 @@ #if LV_LOG_PRINTF #include #endif + /********************* * DEFINES *********************/