Change bufferedImage pixels in java - java

I have a small problem.
I have a BufferedImage which has pixels that have an RGB value.
This code is used to create an RGB value from de R, G, B, A values.
private int getRGB(int r, int g, int b, int a){
return (a << 24) | (r << 16) | (g << 8) | b;
}
The first question is, how can i get the R, G, B, A values from a Pixel, because the pixel RGB will return the number that is generated by the code above.
And if I have those values, can I put 2 pixels on top of each other so it calculates the new values or do I have to do that by manual?
With automatic calculation you can think of Java 2D when you put 2 transport things on top it will merge the colors.
Thank you very much.

The first question is, how can i get the R, G, B, A values from a Pixel, because the pixel RGB will return the number that is generated by the code above.
You can reverse the process as follows:
int a = (argb >> 24) & 0xFF;
int r = (argb >> 16) & 0xFF;
int g = (argb >> 8) & 0xFF;
int b = (argb >> 0) & 0xFF;
And if I have those values, can I put 2 pixels on top of each other so it calculates the new values or do I have to do that by manual? With automatic calculation you can think of Java 2D when you put 2 transport things on top it will merge the colors.
You will need to do this manually (or invoking a utility method per-pixel), since you need to decide how to composite the colors, e.g. you could use the maximum, sum, mean etc pixel value.

Related

How to obtain the red, green and blue values from gray value in java?

I obtain the gray value of the pixel by :
val=img.getRGB(j, i) & 0xFF;
for processing purpose.
Now , after processing I want the red, green and blue values back. How do I do this?
Here is some sample code to obtain the r, g, b, alpha, and gray-scale values for a pixel at coordinates (x, y) on a BufferedImage.
BufferedImage image; // assume you have this image
int rgb = image.getRGB(x, y); // get the desired pixel
int r = (rgb >> 16) & 0xFF;
int g = (rgb >> 8) & 0xFF;
int b = (rgb & 0xFF);
int alpha = (rgb >> 24) & 0xFF;
int gray = (r + g + b) / 3; // rgb are not affected
Use the below:-
int r=(rgb>>16) & 0xff;
int g=(rgb>>8) & 0xff;
int b=(rgb) & 0xff;
where int rgb=img.getRGB(j, i);
Store these values for later retrieval.
Refer: RGB values of an image
In case of a gray image:-
int rgb = (val << 16) | (val << 8) | (val << 0);
You can get the rgb value of gray image like above, and then apply the methods of finding r,g and b as mentioned earlier.

Convert negative rgb value to int [duplicate]

Ok so I'm working on a program that takes in an image, isolates a block of pixels into an array, and then gets each individual rgb value for each pixel in that array.
When I do this
//first pic of image
//just a test
int pix = myImage.getRGB(0,0)
System.out.println(pix);
It spits out -16106634
I need to get the (R, G, B) value out of this int value
Is there a formula, alg, method?
The BufferedImage.getRGB(int x, int y) method always returns a pixel in the TYPE_INT_ARGB color model. So you just need to isolate the right bits for each color, like this:
int pix = myImage.getRGB(0, 0);
int r = (pix >> 16) & 0xFF;
int g = (pix >> 8) & 0xFF;
int b = pix & 0xFF;
If you happen to want the alpha component:
int a = (pix >> 24) & 0xFF;
Alternatively you can use the Color(int rgba, boolean hasalpha) constructor for convenience (at the cost of performance).
int pix = myImage.getRGB(0,0);
Color c = new Color(pix,true); // true for hasalpha
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();

Any one tell me why we write this 0xff000000 in filters?

Here is my code for GrayScale filter want to know about this
class GrayScale extends RGBImageFilter {
#Override
public int filterRGB(int x, int y, int rgb) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
rgb = (r * 77 + g * 151 + b * 28) >> 8;
return a | (rgb << 16) | (rgb << 8) | rgb;
}
}
The format of your input is 0xAARRGGBB where AA is the alpha (transparency), RR is the red, GG is the green, and BB is the blue component. This is hexadecimal, so the values range from 00 to FF (255).
Your question is about the extraction of the alpha value. This line:
int a = rgb & 0xFF000000
If you consider a value like 0xFFFFFFFF (white), AND will return whatever bits are set in both the original colour and the mask; so you'll get a value of 0xFF, or 255 (correctly).
The
int a = rgb & 0xff000000;
...
return a | ...;
simply preserves the top 8 bits of rgb (which contain the alpha component).
Beside Ashes999 and NPE answers, if you want to know how it's treated internally in java, check out this post

Getting RGB value out of negative int value

i had to convert from rgb to hsb so as to perform histogram equalization on an image. I have converted it back into rgb and i am getting a negative value like -158435. Can anyone please help me understand how to convert this into a colour so i can set it to my pixel? Thanks
Simply make use of the bit-shifting. It works.
int rgb = 0x00F15D49;
int r = (rgb >>> 16) & 0xFF;
int g = (rgb >>> 8) & 0xFF;
int b = rgb & 0xFF;
Then use this method
Color.RGBtoHSB(int r, int g, int b, float[] hsbvals); like this:
float[] hsb = Color.RGBtoHSB(r, g, b, null);
To convert it back, simply use the other method (edited, you were right):
int rgb = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
System.out.println(Integer.toHexString(rgb));
The negative value appears because you are storing colors as ARGB (Alpha Red Green Blue).
The alpha channel is then often just 100% opaque, which is 255 = 0xFF.
Therefore, when the color is converted to an 32 bit int, it appears negative.
Example: Opaque Black = ARGB(255, 0, 0, 0) = 0xFF000000 = -16777216

signed int to unsigned byte and vice versa

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

Categories