java image-processing colors rgb bufferedimage

java - Comprender los valores de salida BufferedImage.getRGB



image-processing colors (5)

Obtengo un valor entero para el píxel en una imagen usando este método:

int colour = img.getRGB(x, y);

Luego estoy imprimiendo los valores y veo que los píxeles negros corresponden a un valor como "-16777216", un tipo de azul a algo así como "-16755216", etc. ¿Puede alguien explicarme la lógica detrás de este valor?


El color RGB int contiene los componentes Rojo, Verde, Azul del color en sus bits. Tienes que mirar su representación binaria o hexadecimal y no mirarlo como un número entero entero (no mirar su representación decimal).

Un int tiene 32 bits, 3x8 = 24 se usa para almacenar los componentes RGB (8 bits para cada uno) en el siguiente formato:

2 1 0 bitpos 32109876 54321098 76543210 ------ --+--------+--------+--------+ bits ..|RRRRRRRR|GGGGGGGG|BBBBBBBB|

Puede extraer o establecer los componentes usando máscaras de bits:

int color = img.getRGB(x, y); // Components will be in the range of 0..255: int blue = color & 0xff; int green = (color & 0xff00) >> 8; int red = (color & 0xff0000) >> 16;

Si el color también tiene un componente alfa (transparencia) ARGB, obtiene los últimos 8 bits restantes.

3 2 1 0 bitpos 10987654 32109876 54321098 76543210 ------ +--------+--------+--------+--------+ bits |AAAAAAAA|RRRRRRRR|GGGGGGGG|BBBBBBBB|

Y el valor:

int alpha = (color & 0xff000000) >>> 24; // Note the >>> shift // required due to sign bit

Un valor alfa de 255 significa que un color es completamente opaco y un valor de 0 significa que el color es completamente transparente.

Tu color:

Su color es color = -16755216 que tiene:

blue : 240 // Strong blue green: 85 // A little green mixed in red : 0 // No red component at all alpha: 255 // Completely opaque


En realidad, puede transformar la cadena int en binaria por Integer.toBinaryString (-16755216), que es 11111111000000000101010111110000.it compuesto de 4 bytes: alfa, rojo, verde, azul. Los valores no se multiplican, lo que significa que cualquier transparencia se almacena únicamente en el componente alfa y no en los componentes de color. Los componentes se almacenan de la siguiente manera (alpha << 24) | (rojo << 16) | (verde << 8) | azul. Cada componente oscila entre 0..255 con 0, lo que significa que no hay contribución para ese componente, y 255 significa 100% de contribución. Por lo tanto, el negro opaco sería 0xFF000000 (100% opaco pero sin contribuciones de rojo, verde o azul), y el blanco opaco sería 0xFFFFFFFF.


Se explica en los documentos :

Devuelve un píxel entero en el modelo de color RGB predeterminado (TYPE_INT_ARGB) [...]

Entonces obtienes 8 bits de canal alfa, 8 bits de rojo, 8 bits de verde, 8 bits de azul.

Una manera simple (y lenta) de examinar el valor es usar el new java.awt.Color(colour, true); y luego llama a los getters.

O bien, puede imprimir el valor como un valor hexadecimal sin signo de 32 bits: Integer.toString(colour, 16) . Cada dos caracteres de la salida será una parte del conjunto ARGB.


Vea la implementation de ColorModel.getRgb :

589 public int getRGB(int pixel) { 590 return (getAlpha(pixel) << 24) 591 | (getRed(pixel) << 16) 592 | (getGreen(pixel) << 8) 593 | (getBlue(pixel) << 0); 594 }


getRGB(int x, int y) devuelve el valor del píxel de color en la ubicación (x, y) .
Estás malinterpretando el valor devuelto.
Está en el formato binario. como 11 ... 11010101 y que se te da como valor int.
Si desea obtener componentes RGB (es decir, rojo, verde, azul) de ese valor, use la clase Color. p.ej

Color mycolor = new Color(img.getRGB(x, y));

Luego puede obtener el valor Rojo, Verde o Azul usando getRed() , getGreen() , getBlue() , getAlpha() . Luego, estos métodos devolverán un valor int en un formato familiar que tenga el valor 0 < value < 225

int red = mycolor.getRed();

Si no quiere usar la clase Color , necesitará usar operaciones bit a bit para obtener su valor.