2011-03-03 120 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); 

這將清除當前像素的圖形對象。然後,只需回顧你想要的東西。我的例子恢復了以前的合成,因爲你會驚奇地發現這些東西奇怪,這樣你就可以清除像素,並且可以重新開始而不用改變圖形上下文。