我需要将图像中的白色更改为透明。我试过这个.. 它拉动光栅逐行抓取像素并用abgr填充第二个图像。其中a = 0,如果rgb值等于白色,则为255,如果rgb值为dont,则将它们写入第二个图像。
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;}
}
但它很有趣。我做错了什么,请帮忙。 这就是结束...... 编辑 它绝对更好,但它是红色而不是黑色。
答案 0 :(得分:2)
虽然BufferedImage
类型是源的BGR和目标图像的ABGR,但是从getPixels
得到的整数实际上是常见的RGB顺序。并且ABGR图像期望数组处于RGBA顺序。
这个文档没有太多记录,但颜色根据图像的颜色模型(RGB)映射到整数,而不是根据原始缓冲区排序。
所有这一切的结果是,当您将k
元素设置为255时,它实际上是红色值,因此您将获得“红色”图像。实际上,通过将源数组的j+2
值放入目标数组的k+3
值,您可以从原始图像的 blue 值中获取alpha值。
这也意味着您不应该颠倒值的顺序来创建Color
对象以与您的颜色进行比较。
所以这里有一个纠正的循环(请注意,我重命名变量以使其更有意义。你真的不应该使用像r
,x
,{{1}这样的名称,xx
等等,这是不可读的。格式化也很重要!):
c