Now i am able to apply pixel of another image to source image pixel of pg to m. but problem is that i m loosing gradient or fading effect.
public static void main(String[] args){
try {
BufferedImage image = ImageIO.read(new File("c:\\m.png"));
BufferedImage patt = ImageIO.read(new File("c:\\pg.png"));
int f = 0;
int t = 0;
int n = 0;
BufferedImage bff = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
for (int y = 0; y < image.getHeight(); ++y) {
for (int x = 0; x < image.getWidth(); ++x) {
int argb = image.getRGB(x, y);
int nrg = patt.getRGB(x, y);
if(((argb>>24) & 0xff) == 0) {
bff.setRGB(x, y, (255<<24));
} else {
bff.setRGB(x, y, nrg);
}
}
}
System.out.println("Trans : " + t + " Normal : " + n);
File outputfile = new File("c://imagetest.png");
ImageIO.write(bff, "png", outputfile);
} catch (IOException ex) {
}
}
thanks.
0xff000000 is opaque black, 0x00000000 is completely transparent.
What is 0 (the colour you chose)?
Yes, it's transparent.
Try 0xff000000 or even better: argb ^ 0xff000000, which just changes the transparency, instead.
if(((argb>>24) & 0xff) == 0) {
bff.setRGB(x, y, argb ^ 0xff000000);
} else {
bff.setRGB(x, y, argb);
}
For BufferedImage.setRGB(int x, int y, int rgb) the rgb value is made up as follows:
11111111 11111111 11111111 11111111
Alpha Red Green Blue
In your code you test the following:
if (((argb >> 24) & 0xff) == 0)
which tests for an Alpha value of 0, thus completely transparent.
When you find it to be true, you then set the rgb value to 0 with
bff.setRGB(x, y, 0);
So you are setting it to transparent again.
Change that to
bff.setRGB(x, y, (255<<24));
or
bff.setRGB(x, y, 0xff000000); //This should be better
which will change it to an opaque black pixel. This will have a binary value of
11111111000000000000000000000000
Edit: Moritz Petersen's solution should work better as it retains the pixel's colour while removing transparency.
If you would like to set it to a specific colour you could do:
bff.setRGB(x, y, 0xffff0000); // red
bff.setRGB(x, y, 0xff00ff00); // green
bff.setRGB(x, y, 0xff0000ff); // blue
or any combination of red, green and blue values.
Related
Is it possible to get the Color of a specific pixel of an Image?
I know how to get it from a BufferedImage:
Color color = new Color(bufferedImage.getRGB(x, y));
But that doesn't work with a java.awt.Image that looks for example like this:
Image image = null;
try {
image = ImageIO.read(new File("image.png"));
} catch (IOException e) {
e.printStackTrace();
}
Is there a way of doing it? Thanks in advance!
ImageIO.read(file) should return a BufferedImage. You can also use PixelGrabber to get a specific color. Example:
private static Color getSpecificColor(Image image, int x, int y) {
if (image instanceof BufferedImage) {
return new Color(((BufferedImage) image).getRGB(x, y));
}
int width = image.getWidth(null);
int height = image.getHeight(null);
int[] pixels = new int[width * height];
PixelGrabber grabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width);
try {
grabber.grabPixels();
} catch (InterruptedException e) {
e.printStackTrace();
}
int c = pixels[x * width + y];
int red = (c & 0x00ff0000) >> 16;
int green = (c & 0x0000ff00) >> 8;
int blue = c & 0x000000ff;
return new Color(red, green, blue);
}
ToolkitImage also has a method to get the BufferedImage but may return null: Why does ToolkitImage getBufferedImage() return a null?
http://www.rgagnon.com/javadetails/java-0257.html
I'm building an application that uses OCR to read text from an image (using Tess4J for Google's Tesseract), but I want to ignore the tan-colored text and only read the grey.
In the image below, for instance, I only want to read "Ricki" and ignore "AOA".
http://i.imgur.com/daCuTbB.png
To accomplish this, I figured removing the tan color from the image before performing OCR was my best option.
/* Remove RGB Value for Group Tag */
int width = image.getWidth();
int height = image.getHeight();
int[] pixels = new int[width * height];
image.getRGB(0, 0, width, height, pixels, 0, width);
for (int i = 0; i < pixels.length; i++) {
//If pixel is between dark-tan value and light-tan value
if (pixels[i] > 0xFF57513b && pixels[i] < 0xFF6b6145) {
// Set pixel to black
System.out.println("pixel found");
pixels[i] = 0xFF000000;
}
}
image.setRGB(0, 0, width, height, pixels, 0, width);
But this code removes almost all of the grey text as well. You aren't able to simply compare hex color values for a range of values the way I have. Is there another way to approach detecting a range of colors? Or a better different approach to this problem?
haraldK pointed me in the right direction by mentioning converting RGB. Bit shifting to get individual r, g, and b int values from the hex value allowed me to compare the color within a range and black out a range of colors from the image.
int baser = 108; //base red
int baseg = 96; //base green
int baseb = 68; //base blue
int range = 10; //threshold + and - from base values
/* Set all pixels within +- range of base RGB to black */
for (int i = 0; i < pixels.length; i++) {
int a = (pixels[i]>>24) &0xFF; //alpha
int r = (pixels[i]>>16) &0xFF; //red
int g = (pixels[i]>>8) &0xFF; //green
int b = (pixels[i]>>0) &0xFF; //blue
if ( (r > baser-range && r < baser+range) &&
(g > baseg-range && g < baseg+range) &&
(b > baseb-range && b < baseb+range) ) {
pixels[i] = 0xFF000000; //Set to black
}
}
I have a buffered image that is drawn in grayscale, and I would like to convert it to color, where the colors map to some ranges in the gray. For example, all grays between 0-100 map to red, 100-255 map to green. It looks like the buffered image lookup ops are the way to do this, but I'm not entirely sure how to do this. For example, if the RGB of the grayscale image is (50,50,50), I want to convert that pixel to (255,0,0), not (255,255,255). Is the lookup op the right way to go with this?
if the RGB of the grayscale image is (50,50,50), I want to convert that pixel to (255,0,0)
Try this one
try {
BufferedImage image = ImageIO.read(new File("resources/Tulips.jpg"));
BufferedImage newImage = new BufferedImage(image.getWidth(), image.getHeight(),
BufferedImage.TYPE_INT_ARGB);
int newColorRGB = new Color(255, 0, 0).getRGB();
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
Color color = new Color(image.getRGB(x, y));
int red = color.getRed();
int blue = color.getBlue();
int green = color.getGreen();
if (red == 50 && blue == 50 && green == 50) {
newImage.setRGB(x, y, newColorRGB);
} else {
newImage.setRGB(x, y, color.getRGB());
}
}
}
ImageIO.write(newImage, "png", new File("resources/Tulips1.png"));
} catch (IOException e) {
e.printStackTrace();
System.out.println("Sorry, I cannot find that file.");
}
Note: change the image type as per your requirement.
I'm wondering how a person could change the alpha transparency of a color, if given the hex color code. For example if given
Color.red.getRGB()
how could I change it's alpha to 0x80?
To put this in context, I'm working on a static method to tint a BufferedImage, by creating a graphics device from the given image, and rendering a half transparent mask with that, disposing of the graphics, and returning the image. It works, but you have to define the alpha yourself in the given hex color code. I want to give a Color object, and double between 0 and 1.0 to determine the intensity of the tinting. Here's my code so far:
public static Image tintImage(Image loadImg, int color) {
Image gImage = loadImg;
Graphics2D g = gImage.image.createGraphics();
Image image = new Image(new BufferedImage(loadImg.width, loadImg.height, BufferedImage.TYPE_INT_ARGB));
for(int x = 0; x < loadImg.width; x++) {
for(int y = 0; y < loadImg.height; y++) {
if(loadImg.image.getRGB(x, y) >> 24 != 0x00) {
image.image.setRGB(x, y, color);
}
}
}
g.drawImage(image.image, 0, 0, null);
g.dispose();
return gImage;
}
You can construct a new Color from the old one with the lower alpha.
Color cNew = new Color(cOld.getRed(), cOld.getGreen(), cOld.getBlue(), 0x80);
Using the Color(int r, int g, int b, int a) constructor.
When a spaceship is destroyed I create list containg pixels of spaceship's image. Pixels are objects of my Pixel class. After creating list it's added to main list where various actions are performed on them. This is how my code looks like:
//Code which creates an array
List<Pixel> pixels = new LinkedList<>();
BufferedImage buff = (BufferedImage)image;
for (int px = 0; px < buff.getWidth(); px++) {
for (int py = 0; py < buff.getHeight(); py++) {
int rgb = buff.getRGB(px, py);
int red = (rgb & 0x00ff0000) >> 16;
int green = (rgb & 0x0000ff00) >> 8;
int blue = rgb & 0x000000ff;
int alpha = (rgb >> 24) & 0xff;
if (alpha == 255) {
pixels.add(new Pixel(px, py, red, green, blue));
}
}
}
//Pixel class constructor
Pixel(float x, float y, int red, int green, int blue) {
super(x, y);
BufferedImage buff = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
WritableRaster raster = buff.getRaster();
//LOOKS EVERYTHING IS OKAY SINCE THIS LINE SO THE ERROR MUST BE SOMEWHERE IN THOSE 2 LINES
raster.setPixel(0, 0, new int[]{red, blue, green, 255});
image = buff;
}
Short explanation: image is private field of type Image. It's used in repaint() method which paints pixel using drawImage() method. And about my problem: Eveything works almost okay. Pixels are creating on right position but all are violet-color. They have different tones(brighter and darker) but are all violet instead of having the same colors as image's colors! Why is this happening? Why violet? Could someone help me unserstand this strange behaviour?
It's probably a mixup of green and blue values in your setPixel method. Colors are usually given in RGB order, which is how you unpacked them from your BufferedImage.
Instead of
raster.setPixel(0, 0, new int[]{red, blue, green, 255});
try
raster.setPixel(0, 0, new int[]{red, green, blue, 255});
If that doesn't work you may have to tinker with different variable orders in your array until it looks right.