1

I'm new to converting image types. I would like to determine the color of each pixel on the screen. I can read the colors from the frame buffer, but they are all in RGB565. For tracking a certain color, I would like to convert the RGB565 to HSV so I can check the hue.

I've already tried converting it via an online converter from RGB565 to RGB888. For example the RGB565 '08F5' to RGB888 '081BAA'. And then from RGB888 to HSL '233 91% 35%'. However, I can't get this working with c code. The colors are in HEX format and stored per 2 in one register. I made a char array of four for each color.

int colorcodes = IORD_ALTERA_AVALON_PIO_DATA(0x08000000 + 123204);
char colorcodesInHex[9];
snprintf(colorcodesInHex, 9, "%08x\n", colorcodes);

char firstColor[4];
char secondColor[4];

for(int i = 0; i <= 7; i++)
{
    if(i <= 3)
    {
        firstColor[i] = colorcodesInHex[i];
    }
    else if (i >= 4 && i <= 7)
    {
        secondColor[i - 4] = colorcodesInHex[i];
    }
}

Does someone know how to convert the RGB565 to RGB888 and then to HSL in C?

Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40
  • Pet peeve: the colors are stored in various bits of integers. They are not in hex, being "in hex" is a property of a number represented as text, not a number stored in a computer's memory (unless you store it as a textual string, of course). – unwind Jun 24 '19 at 11:19
  • What do you have trouble with ? Extracting the R, G and B values ? Knowing how to re-scale those values ? How to calculate H, S and L from the re-scaled values ? – Sander De Dycker Jun 24 '19 at 11:26
  • Well, actually I've trouble with all of the above. But extracting the R, G and B in binary does work. However re-scaling those to RGB888 and after that to HSL is a big mistery for me. I did find some examples of how to do it online, but they all were not in C. – Alex Bijmolt Jun 24 '19 at 11:34
  • Then please show the part of the code that you have working (extracting the R, G and B values), as well as your attempt at the part that isn't working. – Sander De Dycker Jun 24 '19 at 11:36

1 Answers1

0
  int rgb565 = ...; // 16 bit value with rrrrrggggggbbbbb

  double r = ((rgb565 >> 11) & 0x1F) / 31.0; // red   0.0 .. 1.0
  double g = ((rgb565 >> 5) & 0x3F) / 63.0;  // green 0.0 .. 1.0
  double b = (rgb565 & 0x1F) / 31.0;         // blue  0.0 .. 1.0

  double cmax = max(r, max(g, b));
  double cmin = min(r, min(g, b));
  double delta = cmax - cmin;

  // hue (in °)
  double h_degrees = delta == 0.0 ? 0.0
                     : cmax == r ? 60 * (((g - b) / delta) % 6)
                     : cmax == g ? 60 * (((b - r) / delta + 2)
                     : /* cmax == b ? */ 60 * (((r - g) / delta + 4);

  // saturation
  double s = delta == 0.0 ? 0.0 : delta / (1.0 - abs(cmax + cmin - 1));

  // lightness
  double l = (cmax + cmin)/2;

RGB565 is a 16 packing of red-green-blue. The above is the RGB565 to HSL conversion.

With Hue in degrees 0° to 360°

  • The red/green/blue components are extracted with bit shifting >> and then scaling to 0.0 - 1.0.

  • The resulting lightness is an imperfect average, namely the average of minimal and maximal color component value.

  • The hue, coloredness, is an angle in a color circle divided in the three RGB colors.

  • The saturation, gray tendency, is as defined determined by smaller delta.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138