mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 08:28:12 +01:00
Added 332 color conversion and RGB/BGR/GRB formats (#1381)
This commit is contained in:
parent
b5e6ae0d69
commit
9d2b0b4e03
1 changed files with 90 additions and 0 deletions
|
@ -6,6 +6,7 @@
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
|
|
||||||
inline static uint8_t esp_scale8(uint8_t i, uint8_t scale) { return (uint16_t(i) * (1 + uint16_t(scale))) / 256; }
|
inline static uint8_t esp_scale8(uint8_t i, uint8_t scale) { return (uint16_t(i) * (1 + uint16_t(scale))) / 256; }
|
||||||
|
inline static uint8_t esp_scale(uint8_t i, uint8_t scale, uint8_t max_value = 255) { return (max_value * i / scale); }
|
||||||
|
|
||||||
struct Color {
|
struct Color {
|
||||||
union {
|
union {
|
||||||
|
@ -30,6 +31,8 @@ struct Color {
|
||||||
uint8_t raw[4];
|
uint8_t raw[4];
|
||||||
uint32_t raw_32;
|
uint32_t raw_32;
|
||||||
};
|
};
|
||||||
|
enum ColorOrder : uint8_t { COLOR_ORDER_RGB = 0, COLOR_ORDER_BGR = 1, COLOR_ORDER_GRB = 2 };
|
||||||
|
enum ColorBitness : uint8_t { COLOR_BITNESS_888 = 0, COLOR_BITNESS_565 = 1, COLOR_BITNESS_332 = 2 };
|
||||||
inline Color() ALWAYS_INLINE : r(0), g(0), b(0), w(0) {} // NOLINT
|
inline Color() ALWAYS_INLINE : r(0), g(0), b(0), w(0) {} // NOLINT
|
||||||
inline Color(float red, float green, float blue) ALWAYS_INLINE : r(uint8_t(red * 255)),
|
inline Color(float red, float green, float blue) ALWAYS_INLINE : r(uint8_t(red * 255)),
|
||||||
g(uint8_t(green * 255)),
|
g(uint8_t(green * 255)),
|
||||||
|
@ -43,6 +46,60 @@ struct Color {
|
||||||
g((colorcode >> 8) & 0xFF),
|
g((colorcode >> 8) & 0xFF),
|
||||||
b((colorcode >> 0) & 0xFF),
|
b((colorcode >> 0) & 0xFF),
|
||||||
w((colorcode >> 24) & 0xFF) {}
|
w((colorcode >> 24) & 0xFF) {}
|
||||||
|
inline Color(uint32_t colorcode, ColorOrder color_order, ColorBitness color_bitness = ColorBitness::COLOR_BITNESS_888,
|
||||||
|
bool right_bit_aligned = true) {
|
||||||
|
uint8_t first_color, second_color, third_color;
|
||||||
|
uint8_t first_bits = 0;
|
||||||
|
uint8_t second_bits = 0;
|
||||||
|
uint8_t third_bits = 0;
|
||||||
|
|
||||||
|
switch (color_bitness) {
|
||||||
|
case COLOR_BITNESS_888:
|
||||||
|
first_bits = 8;
|
||||||
|
second_bits = 8;
|
||||||
|
third_bits = 8;
|
||||||
|
break;
|
||||||
|
case COLOR_BITNESS_565:
|
||||||
|
first_bits = 5;
|
||||||
|
second_bits = 6;
|
||||||
|
third_bits = 5;
|
||||||
|
break;
|
||||||
|
case COLOR_BITNESS_332:
|
||||||
|
first_bits = 3;
|
||||||
|
second_bits = 3;
|
||||||
|
third_bits = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
first_color = right_bit_aligned ? esp_scale(((colorcode >> (second_bits + third_bits)) & ((1 << first_bits) - 1)),
|
||||||
|
((1 << first_bits) - 1))
|
||||||
|
: esp_scale(((colorcode >> 16) & 0xFF), (1 << first_bits) - 1);
|
||||||
|
|
||||||
|
second_color = right_bit_aligned
|
||||||
|
? esp_scale(((colorcode >> third_bits) & ((1 << second_bits) - 1)), ((1 << second_bits) - 1))
|
||||||
|
: esp_scale(((colorcode >> 8) & 0xFF), ((1 << second_bits) - 1));
|
||||||
|
|
||||||
|
third_color = (right_bit_aligned ? esp_scale(((colorcode >> 0) & 0xFF), ((1 << third_bits) - 1))
|
||||||
|
: esp_scale(((colorcode >> 0) & 0xFF), (1 << third_bits) - 1));
|
||||||
|
|
||||||
|
switch (color_order) {
|
||||||
|
case COLOR_ORDER_RGB:
|
||||||
|
this->r = first_color;
|
||||||
|
this->g = second_color;
|
||||||
|
this->b = third_color;
|
||||||
|
break;
|
||||||
|
case COLOR_ORDER_BGR:
|
||||||
|
this->b = first_color;
|
||||||
|
this->g = second_color;
|
||||||
|
this->r = third_color;
|
||||||
|
break;
|
||||||
|
case COLOR_ORDER_GRB:
|
||||||
|
this->g = first_color;
|
||||||
|
this->r = second_color;
|
||||||
|
this->b = third_color;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
inline bool is_on() ALWAYS_INLINE { return this->raw_32 != 0; }
|
inline bool is_on() ALWAYS_INLINE { return this->raw_32 != 0; }
|
||||||
inline Color &operator=(const Color &rhs) ALWAYS_INLINE {
|
inline Color &operator=(const Color &rhs) ALWAYS_INLINE {
|
||||||
this->r = rhs.r;
|
this->r = rhs.r;
|
||||||
|
@ -140,7 +197,40 @@ struct Color {
|
||||||
Color fade_to_black(uint8_t amnt) { return *this * amnt; }
|
Color fade_to_black(uint8_t amnt) { return *this * amnt; }
|
||||||
Color lighten(uint8_t delta) { return *this + delta; }
|
Color lighten(uint8_t delta) { return *this + delta; }
|
||||||
Color darken(uint8_t delta) { return *this - delta; }
|
Color darken(uint8_t delta) { return *this - delta; }
|
||||||
|
uint8_t to_332(ColorOrder color_order = ColorOrder::COLOR_ORDER_RGB) const {
|
||||||
|
uint16_t red_color, green_color, blue_color;
|
||||||
|
|
||||||
|
red_color = esp_scale8(this->red, ((1 << 3) - 1));
|
||||||
|
green_color = esp_scale8(this->green, ((1 << 3) - 1));
|
||||||
|
blue_color = esp_scale8(this->blue, (1 << 2) - 1);
|
||||||
|
|
||||||
|
switch (color_order) {
|
||||||
|
case COLOR_ORDER_RGB:
|
||||||
|
return red_color << 5 | green_color << 2 | blue_color;
|
||||||
|
case COLOR_ORDER_BGR:
|
||||||
|
return blue_color << 6 | green_color << 3 | red_color;
|
||||||
|
case COLOR_ORDER_GRB:
|
||||||
|
return green_color << 5 | red_color << 2 | blue_color;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint16_t to_565(ColorOrder color_order = ColorOrder::COLOR_ORDER_RGB) const {
|
||||||
|
uint16_t red_color, green_color, blue_color;
|
||||||
|
|
||||||
|
red_color = esp_scale8(this->red, ((1 << 5) - 1));
|
||||||
|
green_color = esp_scale8(this->green, ((1 << 6) - 1));
|
||||||
|
blue_color = esp_scale8(this->blue, (1 << 5) - 1);
|
||||||
|
|
||||||
|
switch (color_order) {
|
||||||
|
case COLOR_ORDER_RGB:
|
||||||
|
return red_color << 11 | green_color << 5 | blue_color;
|
||||||
|
case COLOR_ORDER_BGR:
|
||||||
|
return blue_color << 11 | green_color << 5 | red_color;
|
||||||
|
case COLOR_ORDER_GRB:
|
||||||
|
return green_color << 10 | red_color << 5 | blue_color;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
uint32_t to_rgb_565() const {
|
uint32_t to_rgb_565() const {
|
||||||
uint32_t color565 =
|
uint32_t color565 =
|
||||||
(esp_scale8(this->red, 31) << 11) | (esp_scale8(this->green, 63) << 5) | (esp_scale8(this->blue, 31) << 0);
|
(esp_scale8(this->red, 31) << 11) | (esp_scale8(this->green, 63) << 5) | (esp_scale8(this->blue, 31) << 0);
|
||||||
|
|
Loading…
Reference in a new issue