How to edit pixel values of an image in Java. Is there any method to change pixel values?
For example:
BufferedImage image = ...
image.setRGB(x, y, 0);
From documentation:
void setRGB(int x, int y, int rgb)
//Sets a pixel in this BufferedImage to the specified RGB value.
In BufferedImage: public void setRGB(int x,
int y,
int rgb)
Sets a pixel in this BufferedImage to
the specified RGB value. The pixel is
assumed to be in the default RGB color
model, TYPE_INT_ARGB, and default sRGB
color space. For images with an
IndexColorModel, the index with the
nearest color is chosen.
http://download.oracle.com/javase/6/docs/api/java/awt/image/BufferedImage.html
Related
Should I expect the color of the pixel to be black if
image.getRGB(x, y) returns 0?
My assumption: I would expect 0 because the bit values of each of the values (Red, Green, Blue) would be zero. Am I correct in thinking this?
No, BufferedImage#getRGB() returns hex number. See this unit test:
public class TestRgb {
#Test
public void testBlack(){
BufferedImage bufferedImage = new BufferedImage(1,1, TYPE_BYTE_BINARY);
Graphics2D graphics2D = bufferedImage.createGraphics();
graphics2D.setPaint(new Color(0,0,0)); //black
graphics2D.fillRect(0,0,1,1);
// pass - alpha channel set by default, even on all black pixels
TestCase.assertTrue(bufferedImage.getRGB(0,0)==0xFF000000);
// pass - when looking at just the color values (last 24 bits) the value is 0
TestCase.assertTrue((bufferedImage.getRGB(0,0) & 0x00FFFFFF)==0);
// fail - see above
TestCase.assertTrue(bufferedImage.getRGB(0,0)==0);
}
}
"Returns the RGB value representing the color in the default sRGB ColorModel. (Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are =blue)."
That is, the packing (in hex locations) is as follows, where each component can have a value of 0 (0x00) .. 255 (0xFF).
AARRGGBB
Thus, the final value is not only dependent upon RGB, when all color components are zero:
AA000000
In fact, AA will be 0xFF ("100% opaque") by default unless it has explicitly been set to a different value in a buffer / model that supports an alpha channel.
Im trying to get RGB value from a grayscale image and it was return wrong(?) RGB value. Here is the code.
Color color = new Color(image.getRGB(0, 0));
System.out.print(color.getRed());
System.out.print(color.getGreen());
System.out.print(color.getBlue());
At a color picker was using, the first pixel RGB value R:153,G:153,B:153 but my code print
203203203
Why this thing happened? And also, im trying to use MATLAB Grayscale values for the exact pixel is also 153. Am i doing this wrong?
this is the image
This is because image.getRGB(x, y) by definition returns ARGB values in sRGB colorspace.
From the JavaDoc:
Returns an integer pixel in the default RGB color model (TYPE_INT_ARGB) and default sRGB colorspace. Color conversion takes place if this default model does not match the image ColorModel.
Matlab and other tools likely use a linear RGB or gray color space, and this is why the values are different.
You can get the same values from Java if the image is gray scale (TYPE_BYTE_GRAY), by accessing the Raster and its getDataElements method.
Object pixel = raster.getDataElements(0, 0, null); // x, y, data array (initialized if null)
If the image is TYPE_BYTE_GRAY, pixel will be a byte array with a single element.
int grayValue = ((byte[]) pixel)[0] & 0xff;
This value will be 153 in your case.
Just try this
System.out.println(image.getRaster().getSample(0, 0, 0)); //R
System.out.println(image.getRaster().getSample(0, 0, 1)); //G
System.out.println(image.getRaster().getSample(0, 0, 2)); //B
Here getSample(int x, int y, int b) Returns the sample in a specified band for the pixel located at (x,y) as an int. [According to this]
Parameters:
x - The X coordinate of the pixel location
y - The Y coordinate of the pixel location
b - The band to return b = [0,1,2] for [R,G,B]
and also take a look at BufferedImage getRGB vs Raster getSample
I have a List of java.awt.Image and each of them has a resolution of 300 DPI. I want to print them and when I start to print this images (using javax.PrintService API), printed only piece of some piece of image, because Java's Print/3D classes by default use 72DPI (vs 300 DPI of my images). But when I use images with 72 DPI (with same resolution as the Java default) all images are printed fine (when printing whole images, not only piece of it).
Question: where I can set the printing resolution of my images to fit the printing area?
I tried to set PrintRequestAttributeSet.add( new PrinterResolution(300, 300, ResolutionSyntax.DPI)) but this has no effect.
For now, I scale my images to fit printing area, but after scaling my images I lose quality, so the printed document isn't readable.
You can use drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)
Parameters dx1, dy1, dx2 and dy2 define bounds that your image must fit into. You need to do a few calculations. This should print the high quality image on that coordinates (without scaling it down).
class MyPrintable implements Printable {
public int print(Graphics g, PageFormat pf, int pageIndex) {
if (pageIndex != 0) return NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2D) g;
g2.printImage(....);
return PAGE_EXISTS;
}
}
Then
PrinterJob pj = PrinterJob.getPrinterJob();
...
PageFormat pf = ...;
...
pj.setPrintable(new MyPrintable(), pf);
You still need to set the resolution as you did before.
I have a BufferedImage and would like to set all pixels that are fully transparent to be fully-transparent white (rather than transparent blank, or whatever may be in the source file). I can of course loop through the entire image using getRGB and setRGB, but is there some other way that would be much faster?
You can set the pixels like this:
public void setRGB(int startX,
int startY,
int w,
int h,
int[] rgbArray,
int offset,
int scansize)
This method sets an array of integer pixels in the default RGB color model (TYPE_INT_ARGB) and default sRGB color space, into a portion of the image data. Color conversion takes place if the default model does not match the image ColorModel. There are only 8-bits of precision for each color component in the returned data when using this method. With a specified coordinate (x, y) in the this image, the ARGB pixel can be accessed in this way:
pixel = rgbArray[offset + (y-startY)*scansize + (x-startX)];
I can't say for sure if it is faster, but take a look at the ColorConvertOp class.
I haven't used it personally, but it might be what you are looking for.
I have an image that I want to show some 'spotlights' on, like they do on TV. The rest of the image should be darker than the original, and the person that I'm spotlighting should be normal. I have the x,y and radius of the spotlight, but I'm not sure how to change the brightness at that location.
Also, if I have two spotlights and they intersect, the intersection should be brighter than either of the spotlights.
Use RescaleOp on the original image and subimages. Given that you have a buffered image (called biDest) that contains the image, call RescaleOp(0.6, 0, null) on it to make it darker. Then, to add a (rectangular) spotlight, call the following:
public void spotLight(int x, int y, int w, int h)
{
BufferedImage i = biDest.getSubimage(x, y, w, h);
RescaleOp rescale = new RescaleOp(SPOTLIGHT_BRIGHTNESS, 0, null);
rescale.filter(i, i);
repaint();
}
A simple way is to convert the color to HSL, lower L to darken, increase to lighten, then convert back to RGB and set the pixel.
http://www.mpa-garching.mpg.de/MPA-GRAPHICS/hsl-rgb.html