Panchotiya Vipul
Panchotiya Vipul

Reputation: 1296

Convert JPG to PNG with background transparency

While Converting from JPG to PNG background transparency Image , I don't want a dotted border at converted image

My Original Image (JPG) My Original Image

My Converted Image (PNG)

enter image description here

My source code is

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
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.File;

import javax.imageio.ImageIO;

public class DemoTransparent {

    public static void main(String[] args) throws Exception {

        URL url = new URL("https://i.sstatic.net/jEqbx.jpg");
        Image  image1 = ImageIO.read(url);
        BufferedImage source = (BufferedImage) image1;
        int color = source.getRGB(0, 0);
        Image image = makeColorTransparent(source, new Color(color));
        BufferedImage transparent = imageToBufferedImage(image);
        File out = new File("D:\\Demo.png");
        ImageIO.write(transparent, "PNG", out);

    }

    private static BufferedImage imageToBufferedImage(Image image) {

        BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_4BYTE_ABGR_PRE);

        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() {

            public int markerRGB = color.getRGB() | 0xFF000000;
            public final int filterRGB(int x, int y, int rgb) {
                if ((rgb | 0xFF000000) == markerRGB) {
                    return 0x00FFFFFF & rgb;
                } else {
                    return rgb;
                }
            }


        };
        ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
        return Toolkit.getDefaultToolkit().createImage(ip);
    }

}

I want only png background transparency Image

Upvotes: 6

Views: 2172

Answers (1)

afzalex
afzalex

Reputation: 8652

Normally what we do to extract a color which is exactly equal or nearly equal to a color is take a threshold.

Here is your code with little modifications :

// Take another parameter i.e. threshold
public static Image makeColorTransparent(BufferedImage im, final Color color, float threshold) {
    ImageFilter filter = new RGBImageFilter() {
        public float markerAlpha = color.getRGB() | 0xFF000000;
        public final int filterRGB(int x, int y, int rgb) {
            int currentAlpha = rgb | 0xFF000000;           // just to make it clear, stored the value in new variable
            float diff = Math.abs((currentAlpha - markerAlpha) / markerAlpha);  // Now get the difference
            if (diff <= threshold) {                      // Then compare that threshold value
                return 0x00FFFFFF & rgb;
            } else {
                return rgb;
            }
        }
    };
    ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
    return Toolkit.getDefaultToolkit().createImage(ip);
}

Then call the function as makeColorTransparent(image, color, 0.05f);
But there is a problem in your image. The color of pixels on the corners of oval is exactly equal to the colors of pixel inside (at bottom right) of the oval. So algo is also removing those pixels.

And sadly you cannot include those pixels. I tried to do it with different threshold values. But either the corners are included or some pixels of oval are getting removed. What you can do for this is to use 0.05f as threshold and then paint the areas where you want by hand (Using photoshop or any simple image editor).

enter image description here

Upvotes: 7

Related Questions