Java background transparent

I have a gif image containing only a color shape and a transparent background

I would like to replace the shape color with the one I want (the color palette for this gif is only 2 colors: transparent and white in my case).

I created a filter that correctly replaces white with red (this is a test)

However, I encounter a problem with my imageToBufferedImage method, it removes the transparency and replaces it with black (I donโ€™t know why).

So what I have done so far 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 TestPNG { public static void main(String[] args) throws Exception { File in = new File("bg.gif"); BufferedImage source = ImageIO.read(in); int color = source.getRGB(0, 0); Image image = makeColorTransparent(source, new Color(color), new Color(255, 0, 0)); BufferedImage transparent = imageToBufferedImage(image); File out = new File("bg2.gif"); ImageIO.write(transparent, "gif", 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.setBackground(Color.blue); g2.clearRect(0, 0, 200, 40); g2.drawImage(image, 0, 0, null); g2.dispose(); return bufferedImage; } public static Image makeColorTransparent(BufferedImage im, final Color search, final Color replace) { ImageFilter filter = new RGBImageFilter() { public final int filterRGB(int x, int y, int rgb) { if (rgb == search.getRGB()) { return replace.getRGB(); } else { return rgb; } } }; ImageProducer ip = new FilteredImageSource(im.getSource(), filter); return Toolkit.getDefaultToolkit().createImage(ip); } } 
+4
source share
5 answers

There are 3 problems in the code:

1) Replace

 Image image = makeColorTransparent(source, new Color(color), new Color(255, 0, 0)); 

with

 Image image = makeColorTransparent(source, color, new Color(255, 0, 0)); 

and

 public static Image makeColorTransparent(BufferedImage im, final Color search, final Color replace) { ... if (rgb == search.getRGB()) { ... } 

with

 public static Image makeColorTransparent(BufferedImage im, final int search, final Color replace) { ... if (rgb == search) { ... } 

BECAUSE for some reason source.getRGB(0, 0) ignores the alpha value and turns white ((255, 255, 255, 0) becomes (255, 255, 255, 255))

2) You cannot use int color = source.getRGB(0, 0) because it uses the color of the first pixel (transparent). You should use some other code (for example, request a color in the console) to find out which pixel color to store in int color

3) You clear the color of the BufferedImage bufferedImage in imageToBufferedImage(...) with Color.BLACK (default). Replace //g2.setBackground(Color.blue); on g2.setBackground(new Color(0, 0, 0, 0)); or delete g2.clearRect(...);

+2
source

Are you sure your image supports alpha? First tried drawing a non-black full-size rectangle in bufferedImage?

0
source

Just guessing:

a) Perhaps you do not need the clearRect(...) method.

b) Perhaps you can use something like:

 g2.setColor(new Color(0, 0, 0, 0)); g2.fillRect(...); 
0
source

You have the following:

  g2.drawImage(image, 0, 0, null); 

From Javadoc for this method:

Transparent pixels in an image do not affect all pixels.

Since you cleared your image by filling it with the background color, the pixels are already black, so they remain black.

Try

 g2.setBackground(new Color(0, 0, 0, 0) ); g2.clearRect(0, 0, 200, 40); 

before you draw the image.

0
source

You delete pixels using composite. You cannot just draw transparent pixels over other pixels or any of these garbage. The Porter-Duff rules are clear, and any of them will cause the pixels to mix in accordance with the composite rule. So just change, the rule will clear the pixels.

The problem is that most solutions try to persuade the image to get the pixels you need at the end, using the rule. Change the rule for a second and everything will be easier.

 Composite composite = g.getComposite(); g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR)); g.fillRect(0, 0, bufferedimage.getWidth(), bufferedimage.getHeight()); g.setComposite(composite); 

This will clear the graphic of the current pixels. Then just draw back what you want. My example restored the previous composite, since you will be surprised how often this material looks strange, so you just get cleaned pixels and can start from scratch without changing anything with the graphics context.

0
source

Source: https://habr.com/ru/post/1342152/


All Articles