1

I was calling a url to get image store locally and it's already working, but I'm just want to make sure if the image all white or fully transparency, so that i can skip the image.

URL url = new URL(logoUrl);
InputStream is = url.openStream();
String fileName = logoUrl.substring(logoUrl.lastIndexOf('/') + 1);
//call other service to upload image as byte array.
uploadService.writeFile(request, fileName, IOUtils.toByteArray(is));
afzalex
  • 8,598
  • 2
  • 34
  • 61
fangli
  • 107
  • 3
  • 8
  • 1
    http://stackoverflow.com/questions/10223241/java-check-if-an-image-has-transparency – Madhawa Priyashantha Jul 05 '15 at 08:25
  • Hey guy, as I check it for fully transparency, what about all white color ? – fangli Jul 05 '15 at 08:34
  • 2
    you loop throw the pixels and check color if all you find a color which is not white then return – Madhawa Priyashantha Jul 05 '15 at 08:35
  • The linked 'check transparency' only determines if an alpha channel is present. There might be no alpha channel but still be entirely white; or there may be an alpha channel that is always entirely opaque. Both of these cases fail the check for 'all white or fully [transparent]'. – user2864740 Jul 05 '15 at 08:37

1 Answers1

2

You will have to check all the pixels to check if your image is all white or all transparent. Use PixelGrabber to get all pixels. And if any non fully transparent or non white pixel is found, the image is valid. Here is the code :

public static boolean isValid(String imageUrl) throws IOException, InterruptedException {
    URL url = new URL(imageUrl);
    Image img = ImageIO.read(url);
    //img = img.getScaledInstance(100, -1, Image.SCALE_FAST);
    int w = img.getWidth(null);
    int h = img.getHeight(null);
    int[] pixels = new int[w * h];
    PixelGrabber pg = new PixelGrabber(img, 0, 0, w, h, pixels, 0, w);
    pg.grabPixels();
    boolean isValid = false;
    for (int pixel : pixels) {
        Color color = new Color(pixel);
        if (color.getAlpha() == 0 || color.getRGB() != Color.WHITE.getRGB()) {
            isValid = true;
            break;
        }
    }
    return isValid;
}

You should resize your image for performance issues, This way you will not iterate through all the pixels :

img = img.getScaledInstance(300, -1, Image.SCALE_FAST);

Note : resizing can miss small area that might contain color other than white color. Thus failing this algorithm. But it will rarely happen

Edit :
Here is the test run for following images :

  1. White Image with url https://i.stack.imgur.com/GqRSB.png :
    enter image description here
    System.out.println(isValid("https://i.stack.imgur.com/GqRSB.png"));
    Output : false

  2. Transparent Image with url https://i.stack.imgur.com/n8Wfi.png :
    enter image description here
    System.out.println(isValid("https://i.stack.imgur.com/n8Wfi.png"));
    Output : false

  3. A Valid image with url https://i.stack.imgur.com/Leusd.png :
    enter image description here
    System.out.println(isValid("https://i.stack.imgur.com/Leusd.png"));
    Output : true

afzalex
  • 8,598
  • 2
  • 34
  • 61
  • Thank @afzalex, let's try for now – fangli Jul 05 '15 at 08:55
  • I have call a url to get image like code below, and use your function but it's always return invalid URL url = new URL("http://us.farrow-ball.com/pws/client/images/catalogue/products/102005/large/102005.jpg"); Image img = ImageIO.read(url); – fangli Jul 05 '15 at 09:10
  • I used `Image img = null` in my code. Which is definitely invalid. I didn't had any image to experiment with. You should provide your image here. Like this : `Image img = ImageIO.read(url)` – afzalex Jul 05 '15 at 09:15
  • Yes, i'm using the same as your code and here is the white image url: http://us.farrow-ball.com/pws/client/images/catalogue/products/102005/large/102005.jpg%22 – fangli Jul 05 '15 at 09:17
  • Friend, This url is not directing to any image. It is outputting just text but without any matter. – afzalex Jul 05 '15 at 09:19
  • Oh I'm sorry that above link have contain double quote at the end. but I have tried several all white image and mutiple color image, but still get isValid=true – fangli Jul 05 '15 at 09:35
  • @fangli Sorry! you were right. Actually I have not tested my code and thought it will be correct. The problem was I used `!= 0` instead of `== 0`. I had to exclude things that are fully transparent. Now I tested my code for fully transparent, fully white, and other images that will be valid. – afzalex Jul 05 '15 at 09:51
  • I found another issue with this code. The Color constructor that takes a single int argument defaults the alpha to 255 (per the javadoc) so color.getAlpha() will always return 255 for that code. I think the easiest way to get alpha would be do a bitmask so int alpha = color & 0xff000000; and then using that alpha instead. – zelinka Sep 25 '20 at 15:36