2011-03-03 122 views
4

我有一个GIF图像至极只包含一个花形和透明背景java的背景透明

我想用一个我想要替换形状的颜色(颜色PALET这个GIF只有2种颜色:在我的情况下透明和白色)。

我创建了一个过滤器至极正确地用红色代替白(这是一个测试)

但是我遇到我的方法imageToBufferedImage的问题,它消除了透明度,并用黑色代替它(唐”不知道为什么)。

那么我迄今所做的是:

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); 
    } 

} 
+0

我需要指定取下过滤网还是引起了黑色,而不是透明 的相同问题,所以这个问题或者来自Toolkit.getDefaultToolkit()的createImage(im.getSource()),或从imageToBufferedImage方法 – Bouki 2011-03-04 08:53:29

回答

0

确保图像支持Alpha通道? 尝试首先将非黑色全尺寸矩形绘制到bufferedImage中?

+0

的用于测试的图像可以在这里找到: [链接](http://data.imagup.com/4/1113836851.gif) – Bouki 2011-03-03 16:57:56

+0

我的意思是这行:'Image image = makeColorTransparent(source,new Color(color) ,新颜色(255,0,0));'你在这里只使用RGB颜色,所以我认为alpha通道不支持 - – Thomas 2011-03-03 18:26:42

+0

加入alpha参数变化没有问题 – Bouki 2011-03-04 08:21:54

0

只是猜测:

一)也许你并不需要clearRect(...)方法。

B)也许你可以使用类似:

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

你有这样的:

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

从Javadoc中此方法:图像中

透明像素做不会影响已经存在的任何像素。

由于您清除了图像,使用背景色填充图像,因此像素已经是黑色,因此它们保持黑色。

尝试

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

画的图像之前。

+0

这样做不起作用 它会从颜色调色板中删除透明度,所以我的图像现在全是红色 – Bouki 2011-03-03 16:55:23

+0

@Bouki:你能提供gif吗? – 2011-03-03 16:57:37

+0

用于测试的图像可在此处获得: [链接](http://data.imagup.com/4/1113836851.gif) – Bouki 2011-03-03 16:59:51

2

有3个问题,在您的代码:

1)更换

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

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

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

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

因为某种原因,source.getRGB(0, 0)忽略阿尔法值,并将其变成白色((255,255,255,0)变为(255,255,255,255))

2),则可以” t使用int color = source.getRGB(0, 0),因为它使用第一个像素的颜色(透明)。您应该使用一些其他的代码(如要求在控制台的颜色),以找出像素的颜色int color

3)你正在清理的BufferedImage bufferedImageimageToBufferedImage(...)Color.BLACK(默认颜色)来存储。将//g2.setBackground(Color.blue);替换为g2.setBackground(new Color(0, 0, 0, 0));或删除g2.clearRect(...);

0

使用复合清除像素。您不能只在其他像素或任何垃圾上绘制透明像素。 Porter-Duff规则很清晰,任何这些规则都会根据复合规则使像素混合。所以只需改变,规则就可以清除像素。

问题是,大多数解决方案都试图哄骗图像获取最终像素,使用规则。更改规则一秒钟,一切都变得更容易。

Composite composite = g.getComposite(); 

g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR)); 
g.fillRect(0, 0, bufferedimage.getWidth(), bufferedimage.getHeight()); 

g.setComposite(composite); 

这将清除当前像素的图形对象。然后,只需回顾你想要的东西。我的例子恢复了以前的合成,因为你会惊奇地发现这些东西奇怪,这样你就可以清除像素,并且可以重新开始而不用改变图形上下文。