ESPHome  2022.11.3
display_color_utils.h
Go to the documentation of this file.
1 #pragma once
2 #include "esphome/core/color.h"
3 
4 namespace esphome {
5 namespace display {
6 enum ColorOrder : uint8_t { COLOR_ORDER_RGB = 0, COLOR_ORDER_BGR = 1, COLOR_ORDER_GRB = 2 };
8 inline static uint8_t esp_scale(uint8_t i, uint8_t scale, uint8_t max_value = 255) { return (max_value * i / scale); }
9 
10 class ColorUtil {
11  public:
12  static Color to_color(uint32_t colorcode, ColorOrder color_order,
13  ColorBitness color_bitness = ColorBitness::COLOR_BITNESS_888, bool right_bit_aligned = true) {
14  uint8_t first_color, second_color, third_color;
15  uint8_t first_bits = 0;
16  uint8_t second_bits = 0;
17  uint8_t third_bits = 0;
18 
19  switch (color_bitness) {
20  case COLOR_BITNESS_888:
21  first_bits = 8;
22  second_bits = 8;
23  third_bits = 8;
24  break;
25  case COLOR_BITNESS_565:
26  first_bits = 5;
27  second_bits = 6;
28  third_bits = 5;
29  break;
30  case COLOR_BITNESS_332:
31  first_bits = 3;
32  second_bits = 3;
33  third_bits = 2;
34  break;
35  }
36 
37  first_color = right_bit_aligned ? esp_scale(((colorcode >> (second_bits + third_bits)) & ((1 << first_bits) - 1)),
38  ((1 << first_bits) - 1))
39  : esp_scale(((colorcode >> 16) & 0xFF), (1 << first_bits) - 1);
40 
41  second_color = right_bit_aligned
42  ? esp_scale(((colorcode >> third_bits) & ((1 << second_bits) - 1)), ((1 << second_bits) - 1))
43  : esp_scale(((colorcode >> 8) & 0xFF), ((1 << second_bits) - 1));
44 
45  third_color = (right_bit_aligned ? esp_scale(((colorcode >> 0) & ((1 << third_bits) - 1)), ((1 << third_bits) - 1))
46  : esp_scale(((colorcode >> 0) & 0xFF), (1 << third_bits) - 1));
47 
48  Color color_return;
49 
50  switch (color_order) {
51  case COLOR_ORDER_RGB:
52  color_return.r = first_color;
53  color_return.g = second_color;
54  color_return.b = third_color;
55  break;
56  case COLOR_ORDER_BGR:
57  color_return.b = first_color;
58  color_return.g = second_color;
59  color_return.r = third_color;
60  break;
61  case COLOR_ORDER_GRB:
62  color_return.g = first_color;
63  color_return.r = second_color;
64  color_return.b = third_color;
65  break;
66  }
67  return color_return;
68  }
69  static inline Color rgb332_to_color(uint8_t rgb332_color) {
70  return to_color((uint32_t) rgb332_color, COLOR_ORDER_RGB, COLOR_BITNESS_332);
71  }
72  static uint8_t color_to_332(Color color, ColorOrder color_order = ColorOrder::COLOR_ORDER_RGB) {
73  uint16_t red_color, green_color, blue_color;
74 
75  red_color = esp_scale8(color.red, ((1 << 3) - 1));
76  green_color = esp_scale8(color.green, ((1 << 3) - 1));
77  blue_color = esp_scale8(color.blue, (1 << 2) - 1);
78 
79  switch (color_order) {
80  case COLOR_ORDER_RGB:
81  return red_color << 5 | green_color << 2 | blue_color;
82  case COLOR_ORDER_BGR:
83  return blue_color << 6 | green_color << 3 | red_color;
84  case COLOR_ORDER_GRB:
85  return green_color << 5 | red_color << 2 | blue_color;
86  }
87  return 0;
88  }
89  static uint16_t color_to_565(Color color, ColorOrder color_order = ColorOrder::COLOR_ORDER_RGB) {
90  uint16_t red_color, green_color, blue_color;
91 
92  red_color = esp_scale8(color.red, ((1 << 5) - 1));
93  green_color = esp_scale8(color.green, ((1 << 6) - 1));
94  blue_color = esp_scale8(color.blue, (1 << 5) - 1);
95 
96  switch (color_order) {
97  case COLOR_ORDER_RGB:
98  return red_color << 11 | green_color << 5 | blue_color;
99  case COLOR_ORDER_BGR:
100  return blue_color << 11 | green_color << 5 | red_color;
101  case COLOR_ORDER_GRB:
102  return green_color << 10 | red_color << 5 | blue_color;
103  }
104  return 0;
105  }
106  static uint32_t color_to_grayscale4(Color color) {
107  uint32_t gs4 = esp_scale8(color.white, 15);
108  return gs4;
109  }
110  /***
111  * Converts a Color value to an 8bit index using a 24bit 888 palette.
112  * Uses euclidiean distance to calculate the linear distance between
113  * two points in an RGB cube, then iterates through the full palette
114  * returning the closest match.
115  * @param[in] color The target color.
116  * @param[in] palette The 256*3 byte RGB palette.
117  * @return The 8 bit index of the closest color (e.g. for display buffer).
118  */
119  // static uint8_t color_to_index8_palette888(Color color, uint8_t *palette) {
120  static uint8_t color_to_index8_palette888(Color color, const uint8_t *palette) {
121  uint8_t closest_index = 0;
122  uint32_t minimum_dist2 = UINT32_MAX; // Smallest distance^2 to the target
123  // so far
124  // int8_t(*plt)[][3] = palette;
125  int16_t tgt_r = color.r;
126  int16_t tgt_g = color.g;
127  int16_t tgt_b = color.b;
128  uint16_t x, y, z;
129  // Loop through each row of the palette
130  for (uint16_t i = 0; i < 256; i++) {
131  // Get the pallet rgb color
132  int16_t plt_r = (int16_t) palette[i * 3 + 0];
133  int16_t plt_g = (int16_t) palette[i * 3 + 1];
134  int16_t plt_b = (int16_t) palette[i * 3 + 2];
135  // Calculate euclidean distance (linear distance in rgb cube).
136  x = (uint32_t) std::abs(tgt_r - plt_r);
137  y = (uint32_t) std::abs(tgt_g - plt_g);
138  z = (uint32_t) std::abs(tgt_b - plt_b);
139  uint32_t dist2 = x * x + y * y + z * z;
140  if (dist2 < minimum_dist2) {
141  minimum_dist2 = dist2;
142  closest_index = (uint8_t) i;
143  }
144  }
145  return closest_index;
146  }
147  /***
148  * Converts an 8bit palette index (e.g. from a display buffer) to a color.
149  * @param[in] index The index to look up.
150  * @param[in] palette The 256*3 byte RGB palette.
151  * @return The RGBW Color object looked up by the palette.
152  */
153  static Color index8_to_color_palette888(uint8_t index, const uint8_t *palette) {
154  Color color = Color(palette[index * 3 + 0], palette[index * 3 + 1], palette[index * 3 + 2], 0);
155  return color;
156  }
157 };
158 } // namespace display
159 } // namespace esphome
uint8_t white
Definition: color.h:27
static uint16_t color_to_565(Color color, ColorOrder color_order=ColorOrder::COLOR_ORDER_RGB)
uint8_t g
Definition: color.h:18
static uint32_t color_to_grayscale4(Color color)
static uint8_t color_to_332(Color color, ColorOrder color_order=ColorOrder::COLOR_ORDER_RGB)
static Color index8_to_color_palette888(uint8_t index, const uint8_t *palette)
uint8_t green
Definition: color.h:19
static uint8_t color_to_index8_palette888(Color color, const uint8_t *palette)
uint8_t blue
Definition: color.h:23
uint8_t b
Definition: color.h:22
Definition: a4988.cpp:4
static Color to_color(uint32_t colorcode, ColorOrder color_order, ColorBitness color_bitness=ColorBitness::COLOR_BITNESS_888, bool right_bit_aligned=true)
uint8_t r
Definition: color.h:14
static Color rgb332_to_color(uint8_t rgb332_color)
uint8_t red
Definition: color.h:15