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.