Reputation: 3907
I'm trying to figure out how to detect if a PNG with alpha channel is opaque or not. If it's opaque, all the pixels have a transparency channel at 100%, hence it should be possible to convert to formats like JPEG which doesn't support transparency.
This answer shows how to detect alpha channel, but not if the image is opaque.
ImageMagick can apparently do it with -format %[opaque]
, but i would like to be able to do it in pure Java.
Do you know if it's possible to perform this opaque detection with ImageIO?
Upvotes: 0
Views: 1112
Reputation: 4723
A thing possible is to use 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 you can find a nice example of the how but by using BufferedImage
directly rather than getting a Raster
first.
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;
}
}
NOTE: This is not my work. I've added the code to make the answer independent of the link. Here is the reference to the source.
Upvotes: 1