In order to get image's height we can use ImageIO.read(new URL("…")).getHeight()
.
My questions:
Do I understand correctly that this method downloads the image to the local computer prior size calculation?
If yes, to where exactly the image is downloaded — to some JVM's cache on HDD or directly to the RAM?
Is there any way to take image's height without transfer or download? But with some kind of request to server?
First, your questions:
Kind of. First of all, the ImageIO.read(...)
methods, are convenience methods that will decode the first image in a file, using all default parameters for decoding. As all ImageIO.read(...)
operations are delegated to format specific plugins or ImageReader
instances (like JPEGImageReader
), this may be plugin specific. But the general case, is that the image data is transferred and decoded "on the fly". Note that there's no "size calculation" here, rather the entire image is decoded to a BufferedImage
in this case. As much data as is needed to decode the first image in the file has to be transferred, but not necessarily stored anywhere on the computer, other than the decoded pixel values.
It depends. There's a setting ImageIO.setUseCache(boolean)
, that controls whether the data is cached on disk or in RAM.
true
, the data is temporarily stored on disk, typically in the default temp directory (see java.io.tempdir
System property).false
the data is temporarily stored in memory while the image is decoded.ImageIO
API does have a lot more granular methods that allows you to get the image dimensions a lot faster, and without downloading/decoding the entire image up front.The faster way of obtaining the image dimensions is:
try (InputStream stream = url.openStream()) {
// The "useCache" setting will decide whether "input" below
// will be disk or memory cached
try (ImageInputStream input = ImageIO.createImageInputStream(stream)) {
ImageReader reader = ImageIO.getImageReaders(input).next(); // TODO: Handle no reader
try {
reader.setInput(input);
// Get dimensions of first image in the stream, without decoding pixel values
int width = reader.getWidth(0);
int height = reader.getHeight(0);
}
finally {
reader.dispose();
}
}
}
Again, depending on image format, the above code should only read as much of the header/meta data as is needed to determine the image dimensions. Most ImageReader
implementations will read all header data for this, but still, it's much faster and involves a lot less data (and memory) than decoding the entire image.
It's hard to make any assumptions as to how much data is or needs to be downloaded, because different formats have headers of varying size, the underlying transport (ie. HTTP) may transfer data in "chunks" etc.