Estoy tratando de hacer un programa que convierta hexadecimal a decimal rgb888 y rgb565 respectivamente.

Ya hice mi programa para convertir hexadecimal al formato rgb888, y mi código se ve así:

String color = "0xFFFF00";
    int hexToRgb = 0;

    color.toLowerCase();
    String[] colorSplited = color.split("0x");
    String splitedConverted = colorSplited[1];

    int R = Integer.valueOf(splitedConverted.substring(0,2), 16);
    int G = Integer.valueOf(splitedConverted.substring(2,4), 16);
    int B = Integer.valueOf(splitedConverted.substring(4,6), 16);

    System.out.println(R + " " + G + " " + B);

Vi algunos artículos donde explicaban que cada componente rgb888 R, G y B está variado por 0 y 2 ^ 8. Mi programa actual no utiliza ese proceso específico, pero obtuve los resultados que necesitaba.

Ahora necesito hacer el mismo programa pero para convertir hexadecimal a rgb565. Mi entrada hexadecimal se ve así:

String color = “0xFFE0”;

Entonces, lo que se convertirá es FFE0.

Para esta entrada, necesito obtener el resultado R = 31, G = 63 y B = 0. Pero no tengo idea de cómo logro este resultado. Lo que obtuve en Internet fue que cada componente RGB está variado por 0 <= R <= 2 ^ 5, 0 <= G <= 2 ^ 6 y 0 <= B <= 2 ^ 5.

Lamentablemente no soy un experto en matemáticas. ¿Alguien puede ayudarme a comprender las matemáticas detrás de esto o tener alguna sugerencia sobre cómo puedo obtener este resultado?

1
user8593931 18 oct. 2017 a las 16:32

3 respuestas

La mejor respuesta

En primer lugar, cada carácter hexadecimal está codificado por 4 bits. Por lo tanto, tener 4 caracteres hexadecimales significa que tiene 16 bits para codificar un color.

RGB565 usa 5 bits para el rojo, 6 bits para el verde y 5 bits para el azul. Tener n bits para un color significa que tendrá 2 ^ n valores posibles. 2 ^ 5 = 32 y 2 ^ 6 = 64, de aquí provienen los diferentes valores para cada color que obtuvo de Internet.

Para dividir el valor RGB565 en cada color separado, necesitaría extraer los bits correspondientes para cada uno de ellos, por ejemplo, así:

int redMask   = 0b1111100000000000;
int greenMask = 0b0000011111100000;
int blueMask  = 0b0000000000011111;

String color = "0xFFE0";
int colorAsInteger = Integer.parseInt(color.substring(2,color.length()), 16); // convert the Hex value to int

int R = (colorAsInteger & redMask) >> 11; // keep only red bits
int G = (colorAsInteger & greenMask) >> 5; // keep only green bits
int B = colorAsInteger & blueMask; // keep only blue bits

System.out.println(R + " " + G + " " + B);
1
Bernat 18 oct. 2017 a las 13:56

No puede simplemente dividir la cadena como lo estaba haciendo para el formato rgb888. Lo que debe hacer es convertir la cadena completa en un número y luego dividir este número usando un desplazamiento de bits como este:

    String color = "0xFFE0";
    int rgb = Integer.valueOf(color.substring(2,6), 16);
    int r = (rgb & 0b1111100000000000) >> 11;
    int g = (rgb & 0b0000011111100000) >> 5;
    int b = (rgb & 0b0000000000011111) >> 0;
0
Guillaume Pagès 18 oct. 2017 a las 13:56

La representación hexadecimal típica de los colores RGB es la misma que RGB888, intentaré mostrar esto con ejemplos. Supongo que tenemos el color.

0xFF8800, que es literalmente

1111.1111.1000.1000.0000.0000 como un número binario, donde sus componentes son:

R = FF = 1111.1111 = 255 (los puntos son solo para ayudar a la vista)

G = 88 = 1000.1000 = 136

B = 00 = 0000.0000 = 0

Entonces, la traducción es inmediata (bueno, no hay traducción), y cada componente puede tener un valor de 00 a FF (0 a 255 en base decimal)

El caso con RGB565 es diferente. Solo tiene 5 bits (o 6 en caso de verde) para representar ese componente del color.

Puede ver cada componente como el porcentaje de participación en el color global.

En el ejemplo de 0xFF8800:

El componente rojo participa con un 100% (tiene el valor máximo posible para un componente, 255)

Green participa con un 53.33% (tiene el valor 136 sobre 255)

Azul participa con un 0%, este es obvio.

Si aplica estos porcentajes de color al color RGB565, obtendrá los valores de cada componente.

Entonces, para traducir 0xFF8800 a RGB565, calcule cada porcentaje

R = 1 * 31 = 31 //(percentage over 100 by the maximum value of red in RGB565 = 2^5, minus 1)

G = 0.5333 * 63 = 33.6 //(you should round this value to integer)

B = 0 * 31 = 0

Con esto, el número final es:

  31    34    0

11111.100010.00000

      or

1111.1100.0100.0000

     in hex

0xFC40

No estoy seguro si la explicación es la mejor, pero espero que ayude.

1
alseether 18 oct. 2017 a las 14:00