问题
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?
回答1:
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 allImageIO.read(...)
operations are delegated to format specific plugins orImageReader
instances (likeJPEGImageReader
), 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 aBufferedImage
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.- If the setting is
true
, the data is temporarily stored on disk, typically in the default temp directory (seejava.io.tempdir
System property). - If the setting is
false
the data is temporarily stored in memory while the image is decoded.
- If the setting is
No, not unless your server has a special API to give you this data, and you perform specific requests against this API. However, the
ImageIO
API does have a lot more granular methods that allows you to get the image dimensions a lot faster, ans 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.
回答2:
The answer is that the read()
method has to complete and return a value befor the getHeight()
method can be called.
This isn't even an ImageIO
question, it is just basic Java syntax and semantics.
来源:https://stackoverflow.com/questions/35925981/is-there-any-way-in-java-to-take-image-width-and-height-without-transfer-or-down