I a have the red, green and blue values of a pixel seperately. How to convert them into RBG format to create a new image? I basically need a reverse process for this:
int red = (rgb >> 16) & 0xFF;
int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF;
int rgb = ((r << 16) | ((g << 8) | b);
assuming it's RGB888. Make sure r,g and b are all in the 0-255 range
It's a great practice to use the java.awt.Color class instead.
It will make the things simpler and easier. In your case it would be:
Color myColor = new Color(red, green, blue); //Construct the color
myColor.getRGB(); //Get the RGB of the constructed color
Or the inverse:
Color myColor = new Color(rgb); //Construct the color with the RGB value
myColor.getRed(); //Get the separate components of the constructed color
myColor.getGreen();
myColor.getBlue();
For more info, consult the Javadocs.
Related
So in a BufferedImage, you receive a single integer that has the RGB values represented in it. So far I use the following to get the RGB values from it:
// rgbs is an array of integers, every single integer represents the
// RGB values combined in some way
int r = (int) ((Math.pow(256,3) + rgbs[k]) / 65536);
int g = (int) (((Math.pow(256,3) + rgbs[k]) / 256 ) % 256 );
int b = (int) ((Math.pow(256,3) + rgbs[k]) % 256);
And so far, it works.
What I need to do is figure out how to get an integer so I can use BufferedImage.setRGB(), because that takes the same type of data it gave me.
I think the code is something like:
int rgb = red;
rgb = (rgb << 8) + green;
rgb = (rgb << 8) + blue;
Also, I believe you can get the individual values using:
int red = (rgb >> 16) & 0xFF;
int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF;
int rgb = ((r&0x0ff)<<16)|((g&0x0ff)<<8)|(b&0x0ff);
If you know that your r, g, and b values are never > 255 or < 0 you don't need the &0x0ff
Additionaly
int red = (rgb>>16)&0x0ff;
int green=(rgb>>8) &0x0ff;
int blue= (rgb) &0x0ff;
No need for multipling.
if r, g, b = 3 integer values from 0 to 255 for each color
then
rgb = 65536 * r + 256 * g + b;
the single rgb value is the composite value of r,g,b combined for a total of 16777216 possible shades.
int rgb = new Color(r, g, b).getRGB();
To get individual colour values you can use Color like following for pixel(x,y).
import java.awt.Color;
import java.awt.image.BufferedImage;
Color c = new Color(buffOriginalImage.getRGB(x,y));
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();
The above will give you the integer values of Red, Green and Blue in range of 0 to 255.
To set the values from RGB you can do so by:
Color myColour = new Color(red, green, blue);
int rgb = myColour.getRGB();
//Change the pixel at (x,y) ti rgb value
image.setRGB(x, y, rgb);
Please be advised that the above changes the value of a single pixel. So if you need to change the value entire image you may need to iterate over the image using two for loops.
thank you for your time :). I have already taken a look at Format of TYPE_INT_RGB and TYPE_INT_ARGB and now know how to convert this TYPE_INT_RGB into 4 separate values, but if I were to do a modification to each (say add 20 to each, so Alpha+=20, red+=20, and so on) how would I recombine these values into this TYPE_INT_RGB formatting? Thank you!
// to extract the components into individual ints.
int argb = something();
int red = 0xFF & ( argb >> 16);
int alpha = 0xFF & (argb >> 24);
int blue = 0xFF & (argb >> 0 );
int green = 0xFF & (argb >> 8 );
// to recreate the argb
int argb = (alpha << 24) | (red << 16 ) | (green<<8) | blue;
I would use java.awt.Color for this.
int ARGB = new Color(red, green, blue, alpha).getRGB();
I guess you are using bitwise operations to pull out the individual color channels, but again the Color class can hide those gory details.
Color color = new Color(ARGB);
int red = color.getRed();
int green = color.getGreen();
// etc.
I believe this should work
int RGB = alpha;
RGB = (RGB << 8) + red;
RGB = (RGB << 8) + green;
Rgb = (RGB << 8) + blue;
There's another way without bit shifting, but I'm sure you'll figure it out.
This one is okay, too:
int rgba = new java.awt.Color(r,g,b,a).getRGB();
I have a signed value e.g. -7368817
when I cast it to byte it will be something like: -113
I convert it to unsigned byte bye & 0xff and it will be something like 143
now I manipulate this byte value and after that I want to whole way back! to get the signed integer of the new byte. :)
Update
The whole story:
I have an image which is 8-bit depth and gray scale! it means that all pixels are presented using 1 byte
BufferedImage image = ImageIO.read(new File("my_grayscal_8bit_photo.jpg"));
int intPixel = image.getRGB(1, 1);
now I need some bit manipulation in this pixel but since it is int I must convert it to byte first:
byte bytePixel = (byte) intPixel;
and to make it unsigned:
int intPixel2 = bytePixel & 0xff;
now I do my bit manipulation and want to convert it to int and do:
image.setRGB(1, 1, neworiginalint);
The getRGB(int x, int y) method always returns an int pixel in the TYPE_INT_ARGB color model. To manually extract the red, green, blue and alpha values for the pixel you can do this:
int pixel = image.getRGB(1, 1);
int a = (pixel >> 24) & 0xFF;
int r = (pixel >> 16) & 0xFF;
int g = (pixel >> 8) & 0xFF;
int b = pixel & 0xFF;
Or use the Color(int rgba, boolean hasalpha) constructor for convenience (at the cost of performance). Once you've manipulated the red, green, blue and alpha values (in the range of 0 to 255) you can recombine them back into an int for setting pixels:
int newPixel = (a << 24) | (r << 16) | (g << 8) | b;
Using the -7368817 pixel you mentioned with this code, the alpha is 255 (so no transparency) and the red, green and blue values are all 143. Since you're dealing with grayscale you could just pick any of red, green or blue to get the gray value. However on setting the pixel you're going to have set all three to maintain the grayscale since it's RGB. You could shortcut it a bit like so:
int pixel = image.getRGB(1, 1);
// extract your gray value from blue, assume red and green are same
int gray = pixel & 0xFF;
// this method does your manipulation on the gray value, 0 to 255
gray = manipulate(gray);
// recombine back into int, preserving the original alpha
int newPixel = (pixel & 0xFF000000) | (gray << 16) | (gray << 8) | gray;
// now you can set your new pixel
image.setRGB(1, 1, nexPixel);
Basically the trick is to use int as your unsigned byte. Just make sure you keep the values from 0 to 255 and everything should work fine.
Are you asking how to manipulate the least-significant byte in an signed int, without touching the more significant byte?
This can be done like this:
int i = -7368817; // 0xFF8F 8F8F
int b = i & 0xFF; // "signed byte", = 0x8F = 143
b += 0x2C; // your manipulation, result = 0xBB
i = (i & 0xFFFFFF00) | (b & 0xFF); // result of LSB modification = 0xFF8F8FBB
or in one step: i = (i & 0xFFFFFF00) | ((i + 0x2C) & 0xFF); if it is a simple manipulation.
If the manipulation can't ever produce an overflow, you can simply do it on the whole int:
i ^= 0x34; // i = 0xFF8F8FBB
So in a BufferedImage, you receive a single integer that has the RGB values represented in it. So far I use the following to get the RGB values from it:
// rgbs is an array of integers, every single integer represents the
// RGB values combined in some way
int r = (int) ((Math.pow(256,3) + rgbs[k]) / 65536);
int g = (int) (((Math.pow(256,3) + rgbs[k]) / 256 ) % 256 );
int b = (int) ((Math.pow(256,3) + rgbs[k]) % 256);
And so far, it works.
What I need to do is figure out how to get an integer so I can use BufferedImage.setRGB(), because that takes the same type of data it gave me.
I think the code is something like:
int rgb = red;
rgb = (rgb << 8) + green;
rgb = (rgb << 8) + blue;
Also, I believe you can get the individual values using:
int red = (rgb >> 16) & 0xFF;
int green = (rgb >> 8) & 0xFF;
int blue = rgb & 0xFF;
int rgb = ((r&0x0ff)<<16)|((g&0x0ff)<<8)|(b&0x0ff);
If you know that your r, g, and b values are never > 255 or < 0 you don't need the &0x0ff
Additionaly
int red = (rgb>>16)&0x0ff;
int green=(rgb>>8) &0x0ff;
int blue= (rgb) &0x0ff;
No need for multipling.
if r, g, b = 3 integer values from 0 to 255 for each color
then
rgb = 65536 * r + 256 * g + b;
the single rgb value is the composite value of r,g,b combined for a total of 16777216 possible shades.
int rgb = new Color(r, g, b).getRGB();
To get individual colour values you can use Color like following for pixel(x,y).
import java.awt.Color;
import java.awt.image.BufferedImage;
Color c = new Color(buffOriginalImage.getRGB(x,y));
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();
The above will give you the integer values of Red, Green and Blue in range of 0 to 255.
To set the values from RGB you can do so by:
Color myColour = new Color(red, green, blue);
int rgb = myColour.getRGB();
//Change the pixel at (x,y) ti rgb value
image.setRGB(x, y, rgb);
Please be advised that the above changes the value of a single pixel. So if you need to change the value entire image you may need to iterate over the image using two for loops.
I obtain pixel color by
int color = image.getRGB(x,y);
then i want to acquire red, green, blue components separately. How to do that? Maybe using some bitmask?
int green = color&0x00ff00;
apparently not working... :(
To get color components you can use:
import android.graphics.Color;
int r = Color.red(intColor);
int g = Color.green(intColor);
int b = Color.blue(intColor);
int a = Color.alpha(intColor);
int value = image.getRGB(x,y);
R = (byte)(value & 0x000000FF);
G = (byte)((value & 0x0000FF00) >> 8);
B = (byte)((value & 0x00FF0000) >> 16);
A = (byte)((value & 0xFF000000) >> 24);
May need to flip the R, A, or B around.
You forgot to shift the byte to the right:
int green = (color & 0x00ff00) >> 8;
You can use Color constructor and pass the given integer and hasalpha=true:
Color color = new Color(image.getRGB(x,y), true);
getRGB returns the color of type TYPE_INT_ARGB which means it has an alpha channel.