This is one of the ways you can decode Pixel colors out of the integers you get from Android Pixels.
ARGB_8888, stands for Alpha, Reg, Green, Blue. The 8’s stand for the number of bits per channel.
In Android, signed int
‘s are used to represent pixel’s alpha/color information.
Since Android’s language of choice is java, these ints are 32-bit integers, each int
takes 4 bytes.
4 bytes = 32 bits = 8bits + 8bits + 8bits + 8bits.
If you had an int
like 0xFFAABBCC
, each pair of letters on that hexadecimal would mean the following from left to right
{alpha=0xFF}{red=0xAA){green=0xBB}{blue=0xCC}
If you’ve done web programming and played with rgb colors and you didn’t know about this, now it all should click on how your web browser represents colors, except in HTML you don’t deal with the alpha value in the front. On Android’s XML you do.
In bits (binary), the 0xFFAABBCC
value would look like this:
alpha red green blue
0xFF 0xAA 0xBB 0xCC
255 170 187 204
{0b11111111}{0b10101010}{0b10111011}{0b11001100}
If you wanted to look at the entire number in binary/bits, it’d be something like this (leaving spaces for visual help):
0b11111111 10101010 10111011 11001100 == 0xFFAABBCC == 4289379276
So if you wanted to get the red channel (0xAA = 170 = 0b10101010
) , you’d have to move the whole thing towards the right 16 places, and then compare it with only the rightmost 8 bits.
So, we shift 16 places to the right, we’d get rid of the 2 bytes on the right side and end up only with the left half
0b11111111 10101010
Since we only care about those 8 bits on the right, we do an “&” (bitwise “and”) against 0xFF=255=0b111111111
(all 8 rightmost bits set to 1)
0b11111111 10101010 &
0b00000000 11111111
====================
0b00000000 10101010
So with simple right bit shifting and “& 0xff” of the shifted value we can extract the values per channel.
This class also features a “multiplyByFloat()” function, which I was using to multiply to each channel as I was operating with convolution kernels while playing with image filters.
[pastacode lang=”java” manual=”%2F**%20ARGB_8888%20Pixel%20abstraction%20*%2F%0Apublic%20static%20class%20PixelARGB_8888%20%7B%0A%20public%20final%20byte%20a%3B%0A%20public%20final%20byte%20r%3B%0A%20public%20final%20byte%20g%3B%0A%20public%20final%20byte%20b%3B%0A%20public%20final%20int%20intVal%3B%0A%0A%20public%20PixelARGB_8888(final%20int%20argb32bitInt)%20%7B%0A%20%20a%20%3D%20(byte)((argb32bitInt%20%3E%3E%2024)%20%26%200xff)%3B%0A%20%20r%20%3D%20(byte)((argb32bitInt%20%3E%3E%2016)%20%26%200xff)%3B%0A%20%20g%20%3D%20(byte)((argb32bitInt%20%3E%3E%208)%20%26%200xff)%3B%0A%20%20b%20%3D%20(byte)(argb32bitInt%20%26%200xff)%3B%0A%20%20intVal%20%3D%20argb32bitInt%3B%0A%20%7D%0A%0A%20public%20PixelARGB_8888(byte%20a%2C%20byte%20r%2C%20byte%20g%2C%20byte%20b)%20%7B%0A%20%20this.a%20%3D%20a%3B%0A%20%20this.r%20%3D%20r%3B%0A%20%20this.g%20%3D%20g%3B%0A%20%20this.b%20%3D%20b%3B%0A%20%20intVal%20%3D%20(a%20%3C%3C%2024)%20%2B%20(r%20%3C%3C%2016)%20%2B%20(g%20%3C%3C%208)%20%2B%20b%3B%0A%20%7D%0A%0A%20public%20static%20int%20multiplyByFloat(float%20factor%2C%20int%20arg32bitInt)%20%7B%0A%20%20return%20multiplyByFloat(factor%2C%20arg32bitInt%2C%20false)%3B%0A%20%7D%0A%0A%20public%20static%20int%20multiplyByFloat(float%20factor%2C%20int%20argb32bitInt%2C%20boolean%20multiplyAlphaChannel)%20%7B%0A%20%20PixelARGB_8888%20original%20%3D%20new%20PixelARGB_8888(argb32bitInt)%3B%0A%20%20byte%20alpha%20%3D%20original.a%3B%0A%20%20if%20(multiplyAlphaChannel)%20%7B%0A%20%20%20alpha%20%3D%20(byte)(original.a%20*%20factor)%3B%0A%20%20%7D%0A%20%20PixelARGB_8888%20multiplied%20%3D%20new%20PixelARGB_8888(alpha%2C%20(byte)(factor%20*%20original.r)%2C%20(byte)(factor%20*%20original.g)%2C%20(byte)(factor%20*%20original.b))%3B%0A%20%20return%20multiplied.intVal%3B%0A%20%7D%0A%7D” message=”” highlight=”” provider=”manual”/]