In one of the projects I am working on at the moment, I needed to convert the background colour of an image to be transparent so the image looks better on a non-white background.
Looking on the Web, I found the following article from Dustin Marx:
Making White Image Backgrounds Transparent with Java 2D/Groovy
If the link is broken, please download his code from the following link: ImageTransparency.java
The method which makes the background colour transparent is called makeColorTransparent
. This method works pretty well, except in some cases as shown in the example below:
Original image |
Converted image using Dustin’s method |
This is actually quite normal. Indeed, his code is converting a specific colour (#FFFFFF in our case) to be transparent. But what if the background is not homogeneous?
This is the reason why I had to modify his method to add a new parameter called tolerance
:
private Image makeColorTransparent(final BufferedImage im, final Color color, int tolerance) { int temp = 0; if (tolerance < 0 || tolerance > 100) { System.err.println("The tolerance is a percentage, so the value has to be between 0 and 100."); temp = 0; } else { temp = tolerance * (0xFF000000 | 0xFF000000) / 100; } final int toleranceRGB = Math.abs(temp); final ImageFilter filter = new RGBImageFilter() { // The color we are looking for (white)... Alpha bits are set to opaque public int markerRGBFrom = (color.getRGB() | 0xFF000000) - toleranceRGB; public int markerRGBTo = (color.getRGB() | 0xFF000000) + toleranceRGB; public final int filterRGB(final int x, final int y, final int rgb) { if ((rgb | 0xFF000000) >= markerRGBFrom && (rgb | 0xFF000000) <= markerRGBTo) { // Mark the alpha bits as zero - transparent return 0x00FFFFFF & rgb; } else { // Nothing to do return rgb; } } }; final ImageProducer ip = new FilteredImageSource(im.getSource(), filter); return Toolkit.getDefaultToolkit().createImage(ip); }
Such as Photoshop, the tolerance is a percentage value between 0 and 100. The higher the tolerance is, the bigger the range of colours will be.
Let’s take our previous example and apply a 50% tolerance:
That looks much better, isn’t it? 🙂
#1 by Ivan on 24 Mar 2013 - 15:07
The code who you show, isn’t complete. You didn’t use the toleranceRGB variable. So this code works as same the old code. Please correct 🙂
Best regards!!!
#2 by smoreau on 24 Mar 2013 - 17:42
Yes, you are absolutely right.
It seems I did a mistake when I copied-pasted the code. It is now fixed.
Please try again and let me know if it helps.
#3 by Ivan on 25 Mar 2013 - 10:40
Now it’s perfect! Thanks for the help!
Nice article!
Best regards!