Java ImageIO: проверить, непрозрачен ли PNG с альфа-каналом? - PullRequest
0 голосов
/ 08 мая 2020

Я пытаюсь понять, как определить, непрозрачен ли PNG с альфа-каналом. Если он непрозрачный, все пиксели имеют канал прозрачности на 100%, следовательно, должна быть возможность конвертировать в форматы, такие как JPEG, который не поддерживает прозрачность.

Этот ответ показывает, как обнаруживать альфа-канал, но не в том случае, если изображение непрозрачно.

ImageMagick , очевидно, может сделать это с -format %[opaque], но я хотел бы иметь возможность делать это в чистом виде Java.

Знаете ли вы, возможно ли выполнить это определение непрозрачности с помощью ImageIO?

1 Ответ

1 голос
/ 08 мая 2020

Можно использовать BufferedImage#getData и грубую силу, перебирая все пиксели и проверяя их альфа. Если один пиксель не имеет альфа 1.0, изображение не непрозрачное. Здесь вы можете найти хороший пример как , но с использованием 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;
    }
}

ПРИМЕЧАНИЕ: Это не моя работа. Я добавил код, чтобы ответ не зависел от ссылки. Здесь ссылка на источник.

...