从文件中检测空像素

Detect Empty Pixel From File

要查看完整的项目,请在此处查看回购协议。随意克隆和 运行。注意测试图像 https://github.com/AshGale/Image2RGBA

当在 GIMP 中读取部分显示为空(散列)的 PNG 时,读入程序的值为 [0,0,0,255](红色、绿色、蓝色、Alpha)。我希望空位具有 Alpha 0,因此完全为空 [0,0,0,0]。但是值为 [0,0,0,255] 也是全黑。

  1. 问题,如果像素完全为空,即在 gimp 中散列,我如何检查 java。

  2. 然后我如何将其写入带有 bufferedImage 的图像文件。

  3. 如图所示,对于空的图像,alpha值是否应该为0?请建议读取文件或文件格式的方法。

    //代码摘录完整代码见Git

...

for (int i = 0; i < imageHeight; i++) {
    for (int j = 0; j < imageWidth; j++) {

    individualPixel = new Color(buffImage.getRGB(j, i));

    //TODO find a way to detect a empty pixel an keep perfect black
    if(individualPixel.getRed() == 0 
            && individualPixel.getGreen() == 0
            && individualPixel.getBlue() ==0
            ) {                             

        //set pixel at location to empty
        buffRed.setRGB(j, i, getIntFromColor(0, 0, 0, 0));
        buffGreen.setRGB(j, i, getIntFromColor(0, 0, 0, 0));
        buffBlue.setRGB(j, i, getIntFromColor(0, 0, 0, 0));
    }else {
        // RED
        tempPixel = new Color(individualPixel.getRed(), 0, 0, individualPixel.getAlpha());
        buffRed.setRGB(j, i, getIntFromColor(tempPixel.getRed(), 0, 0, tempPixel.getAlpha()));

        // GREEN

        // BLUE
    }

...

ImageIO.write(buffRed, "png", redImg);

这是工作示例,您也可以在我的 github 问题中查看完整内容。 感谢 Thomas 拒绝使用 getAlphaRaster()

// get RGB from image
BufferedImage buffImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);

try {
    buffImage = ImageIO.read(imageFile);
} catch (IOException e) {
}

int imageHeight = buffImage.getHeight();
int imageWidth = buffImage.getWidth();
Color individualPixel = null;
Color tempPixel = null;

BufferedImage buffRed = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
BufferedImage buffGreen = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
BufferedImage buffBlue = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);

WritableRaster imageRaster = buffImage.getAlphaRaster();
int[] pixel = new int[4];
int alpha = 0;

for (int i = 0; i < imageHeight; i++) {
    for (int j = 0; j < imageWidth; j++) {

        individualPixel = new Color(buffImage.getRGB(j, i));

        imageRaster.getPixel(j, i, pixel);
        alpha = pixel[0];//return 0 for empty

        //if(individualPixel.getAlpha() <255 || alpha >0)
            System.out.println(j + "," + i + " : " + individualPixel.getAlpha()+ "-"+alpha+ " =>" +
                    pixel[0] + " " + pixel[1] + " " + pixel[2] + " " + pixel[3]);

        //TODO find a way to detect a empty pixel an keep perfect black
        if(individualPixel.getRed() == 0 
                && individualPixel.getGreen() == 0
                && individualPixel.getBlue() ==0
                & alpha == 0) {                             

            //set pixel at location to empty
            buffRed.setRGB(j, i, getIntFromColor(0, 0, 0, 0));
            buffGreen.setRGB(j, i, getIntFromColor(0, 0, 0, 0));
            buffBlue.setRGB(j, i, getIntFromColor(0, 0, 0, 0));
        }else {
            // RED
            tempPixel = new Color(individualPixel.getRed(), 0, 0, individualPixel.getAlpha());
            buffRed.setRGB(j, i, getIntFromColor(tempPixel.getRed(), 0, 0, tempPixel.getAlpha()));

            // GREEN
            tempPixel = new Color(0, individualPixel.getGreen(), 0, individualPixel.getAlpha());
            buffGreen.setRGB(j, i, getIntFromColor(0, tempPixel.getGreen(), 0, tempPixel.getAlpha()));

            // BLUE
            tempPixel = new Color(0, 0, individualPixel.getBlue(), individualPixel.getAlpha());
            buffBlue.setRGB(j, i, getIntFromColor(0, 0, tempPixel.getBlue(), tempPixel.getAlpha()));
        }
    }   
    System.out.println("");                 
}

// Save Images to path of selected file
try {
    ImageIO.write(buffRed, "png", redImg);
    ImageIO.write(buffGreen, "png", greenImg);
    ImageIO.write(buffBlue, "png", blueImg);
} catch (IOException e) {

    JOptionPane.showMessageDialog(null, "Failed to create RGB files");
    e.printStackTrace();
}

我相信您的原始代码中的问题就是这一行:

individualPixel = new Color(buffImage.getRGB(j, i));

Color 构造函数有效地丢弃了 alpha 分量。 JavaDoc 说(强调我的):

Creates an opaque sRGB color with the specified combined RGB value [...] Alpha is defaulted to 255.

应该是:

individualPixel = new Color(buffImage.getRGB(j, i), true); // hasAlpha = true

这个构造函数 JavaDoc 说:

Creates an sRGB color with the specified combined RGBA value [...] If the hasalpha argument is false, alpha is defaulted to 255.

您真的不必使用 alpha 栅格(并非所有 BufferedImage 都有)来实现这一点,避免它既简单又兼容。

最后,完全透明像素的 R、G 和 B 值并不重要。所以测试它是否全黑可能是一个过于严格的检查(尽管它似乎对你的输入图像工作正常)。

PS:我认为更精确的术语是 "transparent",而不是 "empty"。