2015-07-12 73 views
1

enter image description here我需要將圖像中的白色更改爲透明。我試過這個.. 它拉着柵格一行一行地抓取像素,並用abgr填充第二個圖像。如果rgb值等於白色,則a = 0,如果rgb值不等於255,則將其寫入第二個圖像。如何在圖像中將顏色更改爲透明

package color; 

    import java.awt.Color; 
    import java.awt.image.BufferedImage; 
    import java.awt.image.WritableRaster; 
    import java.io.IOException; 

    import javax.imageio.ImageIO; 
    import javax.swing.ImageIcon; 
    import javax.swing.JLabel; 
    import javax.swing.JOptionPane; 

    public class ColorToAlpha { 
     public static void main(String[] args){ 
      try { 
       BufferedImage i=ImageIO.read(ColorToAlpha.class.getResource("brown.jpg")); 
       JLabel jl=new JLabel(); 
       jl.setIcon(new ImageIcon(rasterToAlpha(i,Color.white))); 
       JOptionPane.showConfirmDialog(null, jl); 
      } catch (IOException e) {} 

     } 
     public static BufferedImage rasterToAlpha(BufferedImage r,Color c){ 
      BufferedImage bi=new BufferedImage(r.getWidth(),r.getHeight(),BufferedImage.TYPE_4BYTE_ABGR); 
      WritableRaster wr2=bi.getRaster(); 
      WritableRaster wr=r.getRaster(); 
      for(int i=0;i<r.getHeight();i++){ 
       int[] xx=new int[4*r.getWidth()];//array for the abgr 
       int[] x=new int[3*r.getWidth()];//array for the bgr 
       wr.getPixels(0, i, r.getWidth(),1,x);//get them line by line 
       for(int j=0,k = 0;j<x.length;j+=3,k+=4){ 
     if(c.equals(new Color(x[j+2], x[j+1],x[j]))){//flip bgr to rgb and check 
     xx[k]=0;xx[k+1]=0;xx[k+2]=0;xx[k+3]=0;//if its the same make it transparent 
     } 
     else{xx[k]=255;xx[k+1]=x[j];xx[k+2]=x[j+1];xx[k+3]=x[j+2];}//make it opaque 
     } 
       wr2.setPixels(0, i, r.getWidth(),1,xx);//write the line 
      } 
      return bi;} 
    } 

但它出來很有趣。我做錯了什麼請幫忙。 這是它結束爲.. 編輯 它明確地說是更好,但它是紅色不是黑色。

definitly better

+0

你是什麼意思的「有趣」? – RealSkeptic

+2

你可以在圖像之前和之後張貼嗎?請在透明圖像後面放置一個背景,以便我們可以知道是什麼。謝謝! ---另外請爲了您自己的理智請重新命名循環變量。我懷疑(不知道)'i','ii'和'iii'之間的混淆是問題的一部分。 ---編輯 - 'xx [iii + 2] = x [i + 1];'---應該是'= x [ii + 1]'? – cxw

+0

是的,這可能是它。這是它感謝 –

回答

2

雖然BufferedImage類型是BGR源和ABGR目標圖像,你是從getPixels得到整數實際上是在普通RGB順序。並且ABGR圖像期望數組處於RGBA順序。

這不是很好記錄,但顏色根據圖像的顏色模型(即RGB)映射到整數,而不是根據原始緩衝區排序。

所有這些的結果是,當您將k元素設置爲255時,實際上它的值爲,因此您會得到一個「紅色」圖像。並且通過將源數組的j+2值放入目標數組的k+3值,您實際上可以從原始圖像的藍色值中獲得Alpha值。

這也意味着您不應該顛倒這些值的順序來創建Color對象以與您的顏色進行比較。

因此,這裏是一個修正循環爲你(請注意,我改名變量,使多一點的感覺。你真的不應該使用的名稱,如rxxxc等,無法辨認。而格式也很重要!):

public static BufferedImage rasterToAlpha(BufferedImage sourceImage, Color origColor) { 

    BufferedImage targetImage = new BufferedImage(sourceImage.getWidth(), 
                sourceImage.getHeight(), 
                BufferedImage.TYPE_4BYTE_ABGR); 
    WritableRaster targetRaster = targetImage.getRaster(); 
    WritableRaster sourceRaster = sourceImage.getRaster(); 

    for (int row = 0; row < sourceImage.getHeight(); row++) { 

     int[] rgba = new int[4 * sourceImage.getWidth()]; 
     int[] rgb = new int[3 * sourceImage.getWidth()]; 

     // Get the next row of pixels 
     sourceRaster.getPixels(0, row, sourceImage.getWidth(), 1, rgb); 

     for (int i = 0, j = 0; i < rgb.length; i += 3, j += 4) { 
      if (origColor.equals(new Color(rgb[i], rgb[i + 1], rgb[i + 2]))) { 
       // If it's the same make it transparent 
       rgba[j] = 0; 
       rgba[j + 1] = 0; 
       rgba[j + 2] = 0; 
       rgba[j + 3] = 0; 
      } else { 
       rgba[j] = rgb[i]; 
       rgba[j + 1] = rgb[i + 1]; 
       rgba[j + 2] = rgb[i + 2]; 
       // Make it opaque 
       rgba[j + 3] = 255; 
      } 
     } 
     // Write the line 
     targetRaster.setPixels(0, row, sourceImage.getWidth(), 1, rgba); 
    } 
    return targetImage; 
} 
+0

你非常感謝你。 –

相關問題