I'm trying to gray out a BufferedImage (not convert it to gray scale, just add a gray tint on top). Right now, I'm doing this by using another image, make it translucent, and then overlay it on top of my original image. This is the code I have for now:
package com.mypkg;
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import javax.imageio.ImageIO;
import org.imgscalr.Scalr;
public class Overlay {
public static void main(String args[]){
URL url = null;
try{
//The gray image used for overlay
url = new URL("https://hoursofidleness.files.wordpress.com/2012/06/gray-card.jpg");
BufferedImage img1 = ImageIO.read(url);
//The original image which I want to gray out
url = new URL("http://www.staywallpaper.com/wp-content/uploads/2016/01/Colorful-Wallpaper-HD-pictures-STAY015.jpg");
BufferedImage img2 = ImageIO.read(url);
BufferedImage reImg2 = Scalr.resize(img2, Scalr.Method.BALANCED, Scalr.Mode.FIT_EXACT, 150, 150);
//Make the gray image, which is used as the overlay, translucent
BufferedImage transparent = new BufferedImage(img1.getWidth(), img1.getHeight(),BufferedImage.TRANSLUCENT);
Graphics2D g2d = transparent.createGraphics();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 0.50));
g2d.drawImage(img1, null, 0, 0);
g2d.dispose();
BufferedImage reImg1 = Scalr.resize(transparent, Scalr.Method.BALANCED, Scalr.Mode.FIT_EXACT, 150, 150);
//Merge both images
BufferedImage result = new BufferedImage(150, 150, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.drawImage(reImg2, 0, 0, null);
g.drawImage(reImg1, 0, 0, null);
g.dispose();
ImageIO.write(result,"png",new File("/result.png"));
} catch(Exception e){
e.printStackTrace();
}
}
}
Is there any other way to achieve this without using an additional image for overlay? Can I simply add a gray tint on top of my original image? I've tried many suggestions which I saw on other posts, but none of them work.
Thanks.
What your method basically does:
First, there is no real need to create the transparent
image. You can use the composite draw directly over the real image.
Second, an image which is entirely gray is no different than a plain rectangle, and the Graphics2D
class has a fillRect
method that draws a filled rectangle, probably a lot faster than drawing an image.
So, after you load and scale your original image into reImg2
, you can use:
Graphics2D g2d = reImg2.createGraphics();
g2d.setColor(new Color(20,20,20,128));
g2d.fillRect(0, 0, reImg2.getWidth(), reImg2.getHeight());
g2d.dispose();
That's it, now reImg2
is darkened and you can write it to your file. Play around with the values - change the 20s to lower value for a darker gray or higher value (up to 255) for lighter gray. Change the 128 (50% alpha) to higher value for a more grayed-out image or to lower value for a less grayed-out image.