Java ImageIO:检查带有 alpha 的 PNG 是否不透明?

Java ImageIO: check if a PNG with alpha is opaque?

我想知道如何检测带有 alpha 通道的 PNG 是否不透明。如果它是不透明的,所有像素都有一个 100% 的透明度通道,因此应该可以转换为不支持透明度的格式,如 JPEG。

This answer 展示了如何检测 alpha 通道,但如果图像不透明则不会。

ImageMagick can apparently do it-format %[opaque],但我希望能够在纯 Java.

中完成

您知道是否可以使用 ImageIO 执行这种不透明检测吗?

一种可能的方法是使用 BufferedImage#getData and brute force going over all the pixels and checking their alpha. If one pixel doesn't have the alpha 1.0, the image isn't opaque. Here 你可以找到 how 的一个很好的例子,但是通过直接使用 BufferedImage 而不是获得 Raster第一。

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class DetectImageTransparency {

    public static void main(String... args) throws IOException {

        File pngInput = new File("/tmp/duke.png");
        BufferedImage pngImage = ImageIO.read(pngInput);
        checkTransparency(pngImage);

        File jpgInput = new File("/tmp/duke.jpg");
        BufferedImage jpgImage = ImageIO.read(jpgInput);
        checkTransparency(jpgImage);
    }

    private static void checkTransparency(BufferedImage image){
        if (containsAlphaChannel(image)){
            System.out.println("image contains alpha channel");
        } else {
            System.out.println("image does NOT contain alpha channel");
        }

        if (containsTransparency(image)){
            System.out.println("image contains transparency");
        } else {
            System.out.println("Image does NOT contain transparency");
        }
    }

    private static boolean containsAlphaChannel(BufferedImage image){
        return image.getColorModel().hasAlpha();
    }

    private static boolean containsTransparency(BufferedImage image){
        for (int i = 0; i < image.getHeight(); i++) {
            for (int j = 0; j < image.getWidth(); j++) {
                if (isTransparent(image, j, i)){
                    return true;
                }
            }
        }
        return false;
    }

    public static boolean isTransparent(BufferedImage image, int x, int y ) {
        int pixel = image.getRGB(x,y);
        return (pixel>>24) == 0x00;
    }
}

注意:这不是我的作品。我添加了代码以使答案独立于 link。 Here 是对源的引用。