wtorek, 10 sierpnia 2021

C - RGB888 to RGB565

W tym poście chciałbym opisać krótką funkcję zmieniającą wartość kolorów z RGB888 na RGB565. 


RGB888 vs RGB565:


Dla RGB888 wartości reprezentowane są w postaci 8 bitów dla każdego koloru (czerwony, zielony, niebieski) czyli na 24 bitach (3 bajty). W przypadku RGB565 wartość przechowywana jest na 2 bajtach  (czerwony 5 bitów, zielony 6 bitów, niebieski 5 bitów).

Ma to duże znaczenie np. przy obsłudze wyświetlaczy. Gdzie spora grupa interfejsów obsługuje tryb RGB565 (zwłaszcza tych tańszych). Co oznacza znacznie zredukowaną ilość dostępnych kolorów do wyświetlenia (RGB888 pozwoli na wyświetlenie 16777216 kolorów, natomiast RGB565 już tylko 65536). Należy to brać pod uwagę robiąc np. przejścia pomiędzy kolorami. Jeśli obraz zostanie przygotowany w wersji kolorystycznej 24bitowej, to na wyświetlaczu obsługującym mniejszą ilość kolorów pojawią się widoczne przejścia pomiędzy poszczególnymi odcieniami (np. w postaci pasków). Dodatkowo sam kolor będzie się różnił między sobą, pomimo wykonanej konwersji.

Prosty program:


Zamiana wartości z 24 bitowej na 16 bitową jest wykonywana przez przesunięcie bitowe oraz usuwanie bitów z poszczególnych bajtów dla koloru czerwonego, zielonego oraz niebieskiego.

  1. #include <stdio.h>
  2. #include <stdint.h>
  3.  
  4. #define COLOR_RED       0x00
  5. #define COLOR_GREEN     0x4C
  6. #define COLOR_BLUE      0x3C
  7.  
  8. #define RED_COLOR_MASK  0x1f
  9. #define GREEN_COLOR_MASK  0x3f
  10. #define BLUE_COLOR_MASK  0x1f
  11.  
  12. uint16_t rgb888_conv_to_rgb565(uint8_t *rgbPtr)
  13. {
  14.     uint8_t red   = rgbPtr[0];
  15.     uint8_t green = rgbPtr[1];
  16.     uint8_t blue  = rgbPtr[2];
  17.  
  18.     return (uint16_t)((((red >> 3) & RED_COLOR_MASK) << 11) |
  19.                       (((green >> 2) & GREEN_COLOR_MASK) << 5) |
  20.                        ((blue >> 3) & BLUE_COLOR_MASK));
  21. }
  22.  
  23. int main()
  24. {
  25.     printf("Convert RGB888 to RGB565\r\n");
  26.    
  27.     uint8_t colorToConvert[3] = {COLOR_RED, COLOR_GREEN, COLOR_BLUE};
  28.     uint16_t convertedColor = rgb888_conv_to_rgb565(&colorToConvert[0]);
  29.    
  30.     printf("RGB565: %u(DEC) 0x%x(HEX)", convertedColor, convertedColor);
  31.  
  32.     return 0;
  33. }

Wynik działania programu jest następujący:

  1. Convert RGB888 to RGB565
  2. RGB565: 615(DEC) 267(HEX)

Wartość także można przekonwertować korzystając z narzędzia online.