Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a color transparent in a BufferedImage and save as PNG

I have been searching the web for this, but I havent found any decent help.

I have a BufferedImage, which I have read in with ImageIO. Now I would like to make a certain color in that image to transparent, and save the image as PNG.

I know I cannot just "paint" the transparent color for obvious reasons, so I am guessing I need some kind of a filter.

Anyone got some sample code for this?

like image 455
corgrath Avatar asked Mar 20 '09 09:03

corgrath


People also ask

Can PNG be made transparent?

The benefit of PNG images is that they have the capability for transparency. Use the remove background tool to create a transparent background for an image, headshot, or logo, which you can then place into a variety of new designs and destinations.

How do I change a PNG image from white to transparent?

This is simple – just save the PNG as a JPG and your JPG will automatically have a white background. That's because when you save a PNG with a transparent background as a JPG, Photoshop automatically replaces the transparent parts of the image with white. That's it for now.


2 Answers

I did that recently, to answer a question of my project manager.
The function transforming gray to transparency is:

  private Image TransformGrayToTransparency(BufferedImage image)   {     ImageFilter filter = new RGBImageFilter()     {       public final int filterRGB(int x, int y, int rgb)       {         return (rgb << 8) & 0xFF000000;       }     };      ImageProducer ip = new FilteredImageSource(image.getSource(), filter);     return Toolkit.getDefaultToolkit().createImage(ip);   } 

Actually, it acts on a gray-level image, so I just copy a RGB component (the R one) to alpha, discarding the others which are identical in my case.
You can adapt it to filter a specific color, eg. with a test of equality or range, etc.
Of course, the BufferedImage must be of BufferedImage.TYPE_INT_ARGB type.

I don't address the question of saving, as it is pretty trivial, but I can add this code page too.

[EDIT] To convert Image to BufferedImage:

BufferedImage dest = new BufferedImage(     imageWidth, imageHeight,     BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = dest.createGraphics(); g2.drawImage(image, 0, 0, null); g2.dispose(); 

[EDIT 2] I come after Christoffer posted his complete solution, but here is mine, I show how to make a range of colors transparent. Can be improved, eg. using HSB components instead.

import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.awt.image.ImageProducer; import java.awt.image.RGBImageFilter; import java.io.*;  import javax.imageio.ImageIO;  public class AddTransparency {   AddTransparency() throws IOException   {     String imagePath = "E:/Documents/images/";     File inFile = new File(imagePath, "map.png");     BufferedImage image = ImageIO.read(inFile);      Image transpImg1 = TransformGrayToTransparency(image);     BufferedImage resultImage1 = ImageToBufferedImage(transpImg1, image.getWidth(), image.getHeight());      File outFile1 = new File(imagePath, "map_with_transparency1.png");     ImageIO.write(resultImage1, "PNG", outFile1);      Image transpImg2 = TransformColorToTransparency(image, new Color(0, 50, 77), new Color(200, 200, 255));     BufferedImage resultImage2 = ImageToBufferedImage(transpImg2, image.getWidth(), image.getHeight());      File outFile2 = new File(imagePath, "map_with_transparency2.png");     ImageIO.write(resultImage2, "PNG", outFile2);   }    private Image TransformGrayToTransparency(BufferedImage image)   {     ImageFilter filter = new RGBImageFilter()     {       public final int filterRGB(int x, int y, int rgb)       {         return (rgb << 8) & 0xFF000000;       }     };      ImageProducer ip = new FilteredImageSource(image.getSource(), filter);       return Toolkit.getDefaultToolkit().createImage(ip);   }    private Image TransformColorToTransparency(BufferedImage image, Color c1, Color c2)   {     // Primitive test, just an example     final int r1 = c1.getRed();     final int g1 = c1.getGreen();     final int b1 = c1.getBlue();     final int r2 = c2.getRed();     final int g2 = c2.getGreen();     final int b2 = c2.getBlue();     ImageFilter filter = new RGBImageFilter()     {       public final int filterRGB(int x, int y, int rgb)       {         int r = (rgb & 0xFF0000) >> 16;         int g = (rgb & 0xFF00) >> 8;         int b = rgb & 0xFF;         if (r >= r1 && r <= r2 &&             g >= g1 && g <= g2 &&             b >= b1 && b <= b2)         {           // Set fully transparent but keep color           return rgb & 0xFFFFFF;         }         return rgb;       }     };      ImageProducer ip = new FilteredImageSource(image.getSource(), filter);       return Toolkit.getDefaultToolkit().createImage(ip);   }    private BufferedImage ImageToBufferedImage(Image image, int width, int height)   {     BufferedImage dest = new BufferedImage(         width, height, BufferedImage.TYPE_INT_ARGB);     Graphics2D g2 = dest.createGraphics();     g2.drawImage(image, 0, 0, null);     g2.dispose();     return dest;   }    public static void main(String[] args) throws IOException   {     AddTransparency at = new AddTransparency();   } } 
like image 83
PhiLho Avatar answered Sep 30 '22 23:09

PhiLho


Thanks to PhilLo here is a complete solution of my demo application.

public static void main(String[] args) throws Exception {          File in = new File("C:\\Users\\Christoffer\\Desktop\\christoffer.jpg");         BufferedImage source = ImageIO.read(in);          int color = source.getRGB(0, 0);          Image image = makeColorTransparent(source, new Color(color));          BufferedImage transparent = imageToBufferedImage(image);          File out = new File("C:\\Users\\Christoffer\\Desktop\\trans.PNG");         ImageIO.write(transparent, "PNG", out);      }      private static BufferedImage imageToBufferedImage(Image image) {          BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);         Graphics2D g2 = bufferedImage.createGraphics();         g2.drawImage(image, 0, 0, null);         g2.dispose();          return bufferedImage;      }      public static Image makeColorTransparent(BufferedImage im, final Color color) {         ImageFilter filter = new RGBImageFilter() {              // the color we are looking for... Alpha bits are set to opaque             public int markerRGB = color.getRGB() | 0xFF000000;              public final int filterRGB(int x, int y, int rgb) {                 if ((rgb | 0xFF000000) == markerRGB) {                     // Mark the alpha bits as zero - transparent                     return 0x00FFFFFF & rgb;                 } else {                     // nothing to do                     return rgb;                 }             }         };          ImageProducer ip = new FilteredImageSource(im.getSource(), filter);         return Toolkit.getDefaultToolkit().createImage(ip);     } 
like image 23
corgrath Avatar answered Sep 30 '22 22:09

corgrath