Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将图像中的颜色更改为透明_Java_Image_Image Processing - Fatal编程技术网

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

Java 如何将图像中的颜色更改为透明,java,image,image-processing,Java,Image,Image Processing,我需要将图像中的白色更改为透明。我试过这个。。 它将光栅逐行抓取像素,并用abgr填充第二幅图像。其中,如果rgb值等于白色,则a=0;如果rgb值不等于白色,则a=255,并将其写入第二个图像 package color; import java.awt.Color; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; import java.io.IOE

我需要将图像中的白色更改为透明。我试过这个。。 它将光栅逐行抓取像素,并用abgr填充第二幅图像。其中,如果rgb值等于白色,则a=0;如果rgb值不等于白色,则a=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;}
    }
包装颜色;
导入java.awt.Color;
导入java.awt.image.buffereImage;
导入java.awt.image.WritableRaster;
导入java.io.IOException;
导入javax.imageio.imageio;
导入javax.swing.ImageIcon;
导入javax.swing.JLabel;
导入javax.swing.JOptionPane;
公共级彩色阿尔法{
公共静态void main(字符串[]args){
试一试{
BuffereImage i=ImageIO.read(ColorToAlpha.class.getResource(“brown.jpg”);
JLabel jl=新的JLabel();
jl.setIcon(新的图像图标(rasterToAlpha(i,Color.white));
JOptionPane.showConfirmDialog(null,jl);
}捕获(IOE){}
}
公共静态缓冲区图像光栅到Alpha(缓冲区图像r,颜色c){
BuffereImage bi=新的BuffereImage(r.getWidth(),r.getHeight(),BuffereImage.TYPE_4BYTE_ABGR);
WritableRaster wr2=bi.getRaster();
WritableRaster wr=r.getRaster();

对于(int i=0;i虽然源图像的
buffereImage
类型为BGR,目标图像的类型为ABGR,但从
getPixels
中获取的整数实际上是通用RGB顺序。ABGR图像希望数组是RGBA顺序

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

所有这一切的结果是,当您将
k
元素设置为255时,它实际上是红色的值,因此您会得到一个“变红”的图像。通过将源数组的
j+2
值放入目标数组的
k+3
值中,您实际上会从原始图像的蓝色值中得到alpha值

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

下面是一个正确的循环(请注意,我重命名了变量以使其更有意义。您确实不应该使用诸如
r
x
xx
c
等名称,这些名称是不可读的。格式也很重要!):

公共静态缓冲图像光栅到Alpha(缓冲图像源图像,颜色或颜色){
BuffereImage targetImage=新的BuffereImage(sourceImage.getWidth(),
sourceImage.getHeight(),
buffereImage.TYPE_4BYTE_ABGR);
WritableRaster targetMaster=targetImage.getRaster();
WritableRaster sourceRaster=sourceImage.getRaster();
对于(int row=0;row
虽然源图像的
buffereImage
类型为BGR,目标图像的类型为ABGR,但从
getPixels
中获取的整数实际上是通用RGB顺序。ABGR图像希望数组是RGBA顺序

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

所有这一切的结果是,当您将
k
元素设置为255时,它实际上是红色的值,因此您会得到一个“变红”的图像。通过将源数组的
j+2
值放入目标数组的
k+3
值中,您实际上会从原始图像的蓝色值中得到alpha值

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

下面是一个正确的循环(请注意,我重命名了变量以使其更有意义。您确实不应该使用诸如
r
x
xx
c
等名称,这些名称是不可读的。格式也很重要!):

公共静态缓冲图像光栅到Alpha(缓冲图像源图像,颜色或颜色){
BuffereImage targetImage=新的BuffereImage(sourceImage.getWidth(),
sourceImage.getHeight(),
buffereImage.TYPE_4BYTE_ABGR);
WritableRaster targetMaster=targetImage.getRaster();
WritableRaster sourceRaster=sourceImage.getRaster();
对于(int row=0;rowpublic 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;
}