如何将图像中的颜色更改为透明

How to change a color to transparent in an Image

我需要将图像中的白色更改为透明。我试过这个.. 它拉光栅逐行抓取像素并用 abgr 填充第二个图像。其中 a =0 如果 rgb 值等于白色或 255 如果 rgb 值 dont.and 将它们写入第二个图像。

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

但结果非常 funny.What 我做错了吗请帮忙。 这就是它的结局…… 编辑 它肯定更好,但它是红色而不是黑色。

虽然 BufferedImage 类型是源图像的 BGR 和目标图像的 ABGR,但您从 getPixels 获得的整数实际上是在常见的 RGB 顺序中。并且 ABGR 图像期望数组按 RGBA 顺序排列。

这没有很好的记录,但是颜色是根据图像的颜色模型(RGB)而不是根据原始缓冲区顺序映射到整数的。

所有这一切的结果是,当您将 k 元素设置为 255 时,它实际上是 red 值,因此您得到 "reddened"图片。通过将源数组的 j+2 值放入目标数组的 k+3 值中,您实际上从原始图像的 blue 值中获得了 alpha 值.

这也意味着您不应该颠倒值的顺序来创建一个 Color 对象来与您的颜色进行比较。

所以这是一个为您更正的循环(请注意,我重命名了变量以使其更有意义。您真的不应该使用 rxxx,c等等,看不懂。格式也很重要!):

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