Codificar RGB en solo dos bytes

Hola, tengo que codificar los colores RGB en solo dos bytes (16 bits), según esto:

2 bytes (16 bits) define the colour in RGB format:

R4R3R2R1R0G5G4G3G2G1G0B4B3B2B1B0 donde

msb : R4R3R2R1R0G5G4G3
lsb : G2G1G0B4B3B2B1B0

Ahora lo tengo así:
int Rcolor;
int Gcolor;
int Bcolor;

int iColorFull ;

// Calculamos el color a emplear.
Rcolor = Rcolor << 11;
Gcolor = Gcolor <<5;
iColorFull = Rcolor|Gcolor|Bcolor;

Ahhh... creo que puede ser:

int Rcolor;
int Gcolor;
int Bcolor;

int iColorFull ;

// Calculamos el color a emplear.
Rcolor = Rcolor << 11;
Gcolor = Gcolor <<6;
iColorFull = Rcolor|Gcolor|Bcolor;

¿No debería ser?:

int Rcolor;
int Gcolor;
int Bcolor;

int iColorFull ;

  // Calculamos el color a emplear.
  Rcolor = Rcolor << 11;
  Gcolor = Gcolor <<5;
  iColorFull = Rcolor|Gcolor|Bcolor;

Ufff............. así lo tengo ahora, pero algunos colores no me salen bien. (En realidad, ya no sé si es cosa de la pantalla....)

Quiero ir degradando un texto, hasta fundirlo al negro, así que voy usando estos RGB:

RGB= 150, 150, 150

RGB= 100, 100, 100

RGB= 50, 50, 50

RGB= 25, 25, 25

RGB= 0, 0, 0

pero en vez de ir siendo cada vez más gris oscuro, me va cambiando de color.... A ver si hoy lo puedo probar, y os digo algo.

Prueba lo siguiente a ver que tal

int Rcolor;
int Gcolor;
int Bcolor;

int iColorFull ;

// Calculamos el color a emplear.
Rcolor = (Rcolor & 0x1f) << 11;
Gcolor = (Gcolor & 0x3f) <<5;
iColorFull = Rcolor|Gcolor|(Bcolor & 0x1f);

No se si serán paranoyas mías pero con la función R4R3R2R1R0G5G4G3G2G1G0B4B3B2B1B0 yo he entendido que hay que coger 5 bits del rojo, 6 bits del verde y 5 bits del azul y si no les haces la máscara entonces se van a mezclar.

Si cada color sólo tiene su color no tiene por qué mezclarse

chiva:
Si cada color sólo tiene su color no tiene por qué mezclarse

RGB tiene una gama de 16,7 millones, cada uno de los colores básicos puede ir desde el 0 hasta el 255 por lo que es necesario un byte para cada color. Con lo cual si queremos guardarlo en 16 bit, se debe de limitar el rango de los colores básicos para que así no se mezclen. Por eso yo he hecho la máscara, para limitarlos.

Aún así creo que lo ideal no sería hacer una máscara, sino poner un numero proporcional a cada uno de los colores básicos, limitando el rango de 0 a 31. No se cómo se verá ya que limitamos mucho el rango total de colores de 16,7 millones a 29791.

Si estoy equivocado agradecería que me corrigieran.

Saludos chato_sat

De momento, no hemos avanzado..... Gracias, en cualquier caso!

Buneo, parece que avanzamos:
Resulta que no se puede emplear un RGB = 150, 150, 150 (por ejemplo)

ya que con los cinco bits asignados al color Red y al color Blue, solo llegas a 31 en decimal. Con 150 desbordamos los cinco bits.

Por eso, para que mi texto vaya desde gris claro hasta negro, poco a poco, para hacer el fundido al negro que necesito, hay que usar siempre valores menores de 31 para todos ellos:

RGB = 30, 30, 30
RGB = 25, 25, 25
RGB = 20, 20, 20
RGB = 15, 15, 15
RGB = 5, 5, 5
RGB = 0, 0, 0

Como he comentado en mi post anterior, podrias probar a pasar los valores que lees a 255 haciendo una regla de tres. Pero entonces los valores que obtengas daran saltos de 8 en 8.

Saludos chato_sat.

RGB es un espacio de color que tiene infintos colores, pero como esto es imposible implementarlo en la práctica, se usan distintas profundidades de color, siendo la de 24 y 32 bits las más comúnes en pantallas de ordenadores. Como los microcontroladores no gozan de tanta memoria y velocidad de procesamiento, se puede usar una profundidad de 16 bits, como la de la pantalla a la que hace referencia el post, lo que nos da una totalidad de 65536 colores.

A lo que me refería con lo de mezclarse, es que si los 3 bits altos del rojo y azul y los 2 del verde son siempre cero, como debieran, no hay que enmascarar nada.
A mi personalmente no me gusta enmascarar por que sí, sin necesidad alguna, ya que esconde fallos, pero si te manejas mejor así, pues tu mismo :smiley:

De todas maneras lo de la pantalla ya se habló hace un tiempo: Pantalla ulcd-144 en modo SGC y Arduino - #4 by system - Español - Arduino Forum

Por si alguien tiene la curiosidad de conocer la pantalla, o simplemente tiene un problema parecido, este es el dispositivo:
http://www.4dsystems.com.au/prod.php?id=79

Gracias a todos,

Si trabajas con colores RGB con 8 bits para cada color (24 bits) y lo quieres pasar al formato comprimido de 16 bits tienes que tener en cuenta lo siguiente:

  • El rojo va a pasar de 8 a 5 bits (desaparecen 3 bits).
  • El verde pasa de 8 a 6 bits (desaparecen 2 bits).
  • El azul pasa de 8 a 5 bits (desaparecen 3 bits).

Los bits que tienes que quedarte son los mas significativos (los de la izquierda), desechando los menos significativos (los de la derecha).

La formas mas rápida de hacer esto es con desplazamientos:

     rojo  = rojo  >> 3;
     verde = verde >> 2;
     azul  = azul  >> 3;

Y luego los unes:

     iColorFull = (rojo << 11) |  (verde << 5) | azul;

Xlopez, muchas gracias, esto es lo que me faltaba por conocer, en el plano teórico. Hoy por la tarde lo pruebo, y os informo del resultado...

Todo ha ido bien.

Gracias...!