I am trying to change color of image. Hence I used the following code
public class Picture {
String img_name;
BufferedImage buf_img;
int width;
int height;
public Picture(String name) {
this.img_name = name;
try {
buf_img = ImageIO.read(new File(img_name));
} catch (IOException ex) {
Logger.getLogger(Picture.class.getName()).log(Level.SEVERE, null, ex);
}
}
public Picture(int w, int h) {
this.width = w;
this.height = h;
buf_img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
public int width() {
width = buf_img.getWidth();
return width;
}
public int height() {
height = buf_img.getHeight();
return height;
}
public Color get(int col, int row) {
Color color = new Color(buf_img.getRGB(col, row));
return color;
}
public void set(int col, int row, Color color) {
buf_img.setRGB(col, row, color.getRGB());
}
public void show() {
try {
File saveAs = new File("D:\\temp\\" + new Random().nextInt() + ".png");
ImageIO.write(buf_img, "png", saveAs);
Desktop.getDesktop().open(saveAs);
} catch (IOException ex) {
Logger.getLogger(Picture.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class ColorSeparation {
public static void main(String[] args) {
// read in the picture specified by command-line argument
Picture picture = new Picture("D:\\qwe1.jpg");
int width = picture.width();
int height = picture.height();
// create three empy pictures of the same dimension
Picture pictureR = new Picture(width, height);
// separate colors
for (int col = 0; col < width; col++) {
for (int row = 0; row < height; row++) {
Color color = picture.get(col, row);
int r = color.getRed();
int g = color.getGreen();
int b = color.getBlue();
pictureR.set(col, row, new Color(r, 0, 0));
}
}
// display picture in its own window
pictureR.show();
}
}
It is working as expected.
.
Now I want to set color of entire image to rgb 255, 153, 51. I tried to set
pictureR.set(col, row, new Color(255, 153, 51)). But the resulted output is the below image.
How can I get correct image? Please help.
Your initial example is misleading you. Your code in the first example is setting varying shades of red (pulled from the original red channel), creating a "redscale" image, not "colorizing" the image like you think it is.
int r = color.getRed();
pictureR.set(col, row, new Color(r, 0, 0));
Your second example is setting a fixed color for each and every pixel, so you get a uniform orange.
pictureR.set(col, row, new Color(255, 153, 51))
You need to colorize the image by varying all three channels, just like you varied the red value initially. See this question for an example using compositing, which is a different angle from what you're using now.
The easiest implementation for you, given your sample code, would be to calculate the relative luminence of each pixel (effectively it's grayscale value) and use that to adjust the "orange" value you are setting. The standard weighting for luminence is
L = 0.2126*R + 0.7152*G + 0.0722*B
so something like
pictureR.set(col, row, new Color(255 * L/255, 153 * L/255, 51 * L/255));
Related
I have a JCheckbox,this is in a JPanel, that is supposed to show an image in the JPanel, when you select it. The problem is this: as you can see in the screenshot, the text of the JCheckbox is difficult to read because of the image.
I was thinking if there was some way to contrast the text to the image, so that the color of the text is the opposite of the image.
I know that there're other ways to fix it, like setting the JCheckbox outside the image, but I'd have to change design of my program and structure code.
For example, here's how I want it to look:
.
This is all the code that the JCheckBox currently has, it is something simple:
final JCheckBox INFO_IMG = new JCheckBox("Ver img");
INFO_IMG.setFont(new Font("Dialog", 0, 12));
INFO_IMG.setBounds(-2, 2, 78, 13);
INFO_IMG.setOpaque(false);
INFO_IMG.setFocusable(false);
INFO_IMG.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(final ItemEvent ie) {
if (1 == ie.getStateChange()) {
INFO_IMG.setText("Ver info");
IMG.setVisible(true);
/* INFO_IMG.setForegound(ROBOT.getPixelColor(
(int)INFO_IMG.getLocationOnScreen.getX() + 12
,(int) INFO_IMG.getLocationOnScreen().getY() + 10));
This is another way that I had thought of,
although it does not work well,would also have to get
the opposite color from the one return.
*/
} else {
INFO_IMG.setText("Ver img");
IMG.setVisible(false);
}
}
});
add(INFO_IMG);
Well, I have found this way to do it, but unfortunately it only works for black and white, can you think of other ways?
Public Color contrast(Image image) {
BufferedImage buffered = toBufferedImage(image);
int black = 0, white = 0;
for (int x = 0; x < buffered.getWidth(); x++) {
for (int y = 0; y < buffered.getHeight(); y++) {
if(buffered.getRGB(x, y) == Color.BLACK.getRGB()) {
black++;
}else {
white++;
}
}
}
System.out.println("Blanco: " + white + ", Negro: " + black);
return (white > black) ? Color.BLACK : Color.WHITE;
}
private BufferedImage toBufferedImage(Image image) {
int width = image.getWidth(null);
int height = image.getHeight(null);
int argb = BufferedImage.TYPE_BYTE_BINARY;
BufferedImage buffered = new BufferedImage(width, height, argb);
Graphics2D g2 = buffered.createGraphics();
g2.drawImage(image, 0, 0, null);
g2.dispose();
// JOptionPane.showMessageDialog(null, new ImageIcon(buffered));
return buffered;
}
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
This question already has an answer here:
How to draw a BufferedImage with a color tint
(1 answer)
Closed 7 years ago.
How would I tint the icon that is passed through here to be a different color? Say I wanted to take a white image and make it a bit darker. I have looked into BufferedImages and such but I can't seem to find anything that will fit into the setup that I am using. I should also note that I am drawing the images onto a JLabel if that makes a difference.
Here is the source that I am using so that you can get an idea as to what I am working with.
public class Icon extends ImageIcon{
private int scale = 1;
private boolean mirror = false;
public Icon(URL url) throws IOException{
super(ImageIO.read(url));
}
public void setScale(int scale){
this.scale = scale;
}
#Override
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D)g.create();
int height = 0, width = this.getIconWidth(), x1 = 1;
if(mirror || scale != 1){
height = -this.getIconHeight();
}
if(mirror){
x1 = -1;
}else{
width = 0;
}
g2.translate(width * scale, height);
g2.scale(x1 * scale, 1 * scale);
super.paintIcon(c, g2, x, y);
}
public boolean isMirror() {
return mirror;
}
public void setMirror(boolean mirror) {
this.mirror = mirror;
}
}
you need to create a new BufferedImage to make the transform into:
public BufferedImage colorImage(BufferedImage loadImg, int red, int green, int blue) {
BufferedImage img = new BufferedImage(loadImg.getWidth(), loadImg.getHeight(),
BufferedImage.TRANSLUCENT);
Graphics2D graphics = img.createGraphics();
Color newColor = new Color(red, green, blue, 0 /* alpha needs to be zero */);
graphics.setXORMode(newColor);
graphics.drawImage(loadImg, null, 0, 0);
graphics.dispose();
return img;
}
I've been working towards grayscaling images in java for some time. I was using a colorConvertOp, but it seems after a load of images were put through the process, eventually the JVM would hang in a locked state in the op.
Now I've started using:
BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_BYTE_GRAY);
Graphics g = image.getGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();
However, I'm seeing a large spike in CPU, where it used to be under 20% and is now up to 120%. It also seems to be causing me memory leaks and eventually OOMs.
Is there an easier, quicker way to grayscale in java without using as much CPU/eliminates hanging from a JVM bug?
I wrote a java program to convert RGB image to GrayScaleImage. Hope this helps
public class GrayScale {
BufferedImage image;
int width;
int height;
public GrayScale() {
try {
File input = new File("input path of the image");
image = ImageIO.read(input);
width = image.getWidth();
height = image.getHeight();
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
Color c = new Color(image.getRGB(j, i));
int red = (int) (c.getRed() * 0.299);
int green = (int) (c.getGreen() * 0.587);
int blue = (int) (c.getBlue() * 0.114);
Color newColor = new Color(red + green + blue,
red + green + blue, red + green + blue);
image.setRGB(j, i, newColor.getRGB());
}
}
File ouptut = new File("output path of the image");
ImageIO.write(image, "jpg", ouptut);
} catch (Exception e) {
}
}
static public void main(String args[]) throws Exception {
GrayScale obj = new GrayScale();
}
}
How can I remove the white pixels of an image before loading it in the Panel
the method for loading image in panel is:
public void ajouterImage(File fichierImage) {
// desiiner une image à l'ecran
try {
monImage = ImageIO.read(fichierImage);
} catch (IOException e) {
e.printStackTrace();
}
repaint();
}
You can't remove a pixel for say from an image, but you sure can change the color of it, or even make it transparent.
Let's say you have a pixel array as a variable somewhere, and you can give it the RGB value of your BufferedImage. The pixel array will be called pixels:
try {
monImage = ImageIO.read(fichierImage);
int width = monImage.getWidth();
int height = monImage.getHeight();
pixels = new int[width * height];
image.getRGB(0, 0, width, height, pixels, 0, width);
for (int i = 0; i < pixels.length; i++) {
// I used capital F's to indicate that it's the alpha value.
if (pixels[i] == 0xFFffffff) {
// We'll set the alpha value to 0 for to make it fully transparent.
pixels[i] = 0x00ffffff;
}
}
} catch (IOException e) {
e.printStackTrace();
}
Assuming that by removing pixels you mean setting them to transparent, you need to set the alpha value of the image to zero. Here is a function colorToAlpha(BufferedImage, Color) which takes a BufferedImage and a Color as input and returns another BufferedImage with the Color set to transparent.
public static BufferedImage colorToAlpha(BufferedImage raw, Color remove)
{
int WIDTH = raw.getWidth();
int HEIGHT = raw.getHeight();
BufferedImage image = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_ARGB);
int pixels[]=new int[WIDTH*HEIGHT];
raw.getRGB(0, 0, WIDTH, HEIGHT, pixels, 0, WIDTH);
for(int i=0; i<pixels.length;i++)
{
if (pixels[i] == remove.getRGB())
{
pixels[i] = 0x00ffffff;
}
}
image.setRGB(0, 0, WIDTH, HEIGHT, pixels, 0, WIDTH);
return image;
}
Example usage:
BufferedImage processed = colorToAlpha(rawImage, Color.WHITE)