12

Why is the following bit of code returns Height: -1 which means that the height is yet not known. How to get height of the image?

 try {
        // Create a URL for the image's location
        URL url = new URL("http://bmw-2006.auto-one.co.uk/wp-content/uploads/bmw-m3-2006-3.jpg");

        // Get the image
        java.awt.Image image = Toolkit.getDefaultToolkit().createImage(url);

        System.out.println("Height: " + image.getHeight(null));


    } catch (MalformedURLException e) {
    } catch (IOException e) {
    }
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Radek
  • 1,403
  • 3
  • 25
  • 54
  • Possible duplicate of http://stackoverflow.com/questions/672916/how-to-get-image-height-and-width-using-java - depending on whether use of the AWT Image class is required. – Ed Staub Nov 18 '11 at 14:41
  • 1
    @berry120 - I was going to say something about Java not wanting to look at the image too long being the problem ... – Brian Roach Nov 18 '11 at 14:41

5 Answers5

17

Use ImageIO.read(URL) or ImageIO.read(File) instead. It will block while loading, and the image width & height will be known after it returns.

E.G.

enter image description here

import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.net.URL;

class SizeOfImage {

    public static void main(String[] args) throws Exception {
        URL url = new URL("https://i.stack.imgur.com/7bI1Y.jpg");
        final BufferedImage bi = ImageIO.read(url);
        final String size = bi.getWidth() + "x" + bi.getHeight();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JLabel l = new JLabel( 
                    size, 
                    new ImageIcon(bi), 
                    SwingConstants.RIGHT );
                JOptionPane.showMessageDialog(null, l);
            }
        });
    }
}

Alternately, add a MediaTracker to the image being loaded asynchronously by the Toolkit and wait until it is completely loaded.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
3

You want something like this:

    try {
        // Create a URL for the image's location
        URL url = new URL("http://bmw-2006.auto-one.co.uk/wp-content/uploads/bmw-m3-2006-3.jpg");

        // Get the image
        Image image = ImageIO.read(url);

        System.out.println("Height: " + image.getHeight(null));


    }
    catch(MalformedURLException e) {
        e.printStackTrace();
    }
    catch(IOException e) {
        e.printStackTrace();
    }

The java.awt.Toolkit approach won't block, so will return -1 and notify the observer (or not in your case because it's null) when it is loaded. If you do want it asynchronously then you'll need to provide a callback in the form of an image observer.

Oh, and don't just ignore exceptions, at least print the stack trace!

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
1

Because the image is loaded asynchronously, in the background.

As the getHeight() javadoc says, you need to provide an ImageObserver (instead of null), which is called when the image has been loaded.

Joonas Pulakka
  • 36,252
  • 29
  • 106
  • 169
1

Toolkit#createImage(...) is non-blocking. Generally I would rather use javax.imageio.ImageIOto read images.

To wait for the Toolkit#createImage(...), use:

MediaTracker mediaTracker = new MediaTracker(component);
mediaTracker.addImage(image);
try {
    mediaTracker.waitForAll();
} catch (InterruptedException e) {
    e.printStackTrace();
}

After that, you can call image.getHeight()

Ingo Kegel
  • 46,523
  • 10
  • 71
  • 102
0

createImage runs in background to load the Image.

use a MediaTracker to wait for the loading and then use getHeight (and use a valid ImageObserver to prevent errors)

Hachi
  • 3,237
  • 1
  • 21
  • 29