Java有没有什么方法可以不用传输不用下载就可以获取图片的宽高?
Is there any way in Java to take image width and height without transfer or download?
为了得到图片的高度我们可以使用ImageIO.read(new URL("…")).getHeight()
.
我的问题:
- 我的理解是否正确,此方法会先将图像下载到本地计算机,然后再计算大小?
- 如果是,图像下载到的确切位置——HDD 上的某些 JVM 缓存或直接到 RAM?
- 有没有什么办法可以不传不下载就可以测高的?但是对服务器有某种请求?
答案是 read()
方法必须完成并且 return 可以调用 getHeight()
方法之前的值。
这甚至不是 ImageIO
问题,它只是基本的 Java 语法和语义。
首先,您的问题:
有点。首先,ImageIO.read(...)
方法是使用所有默认参数解码文件中的 first 图像的便捷方法。由于所有 ImageIO.read(...)
操作都委托给特定插件或 ImageReader
实例(如 JPEGImageReader
),因此此 可能 是特定于插件的。但一般情况下,图像数据被传输和解码"on the fly"。请注意,这里没有 "size calculation",而是 整个图像 在这种情况下被解码为 BufferedImage
。必须传输,但不一定存储在计算机上的任何地方,必须传输解码文件中的第一个图像所需的数据,除了解码后的像素值。
视情况而定。有一个设置 ImageIO.setUseCache(boolean)
,它控制数据是缓存在磁盘上还是缓存在 RAM 中。
- 如果设置为
true
,数据将临时存储在磁盘上,通常在默认的临时目录中(参见 java.io.tempdir
系统 属性)。
- 如果设置为
false
,则在解码图像时将数据临时存储在内存中。
不,除非你的服务器有一个特殊的 API 来给你这个数据,并且你针对这个 API 执行特定的请求。但是,ImageIO
API 确实有很多更精细的方法,可以让您更快地获得图像尺寸,而无需 downloading/decoding 整个图像。
获取图像尺寸的更快方法是:
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();
}
}
}
同样,根据图像格式,上述代码应仅读取确定图像尺寸所需的 header/meta 数据。大多数 ImageReader
实现将为此读取所有 header 数据,但与解码整个图像相比,它仍然更快并且涉及的数据(和内存)少得多。
很难对下载或需要下载多少数据做出任何假设,因为不同的格式有不同大小的 header,底层传输(即 HTTP)可能以 "chunks"等
为了得到图片的高度我们可以使用ImageIO.read(new URL("…")).getHeight()
.
我的问题:
- 我的理解是否正确,此方法会先将图像下载到本地计算机,然后再计算大小?
- 如果是,图像下载到的确切位置——HDD 上的某些 JVM 缓存或直接到 RAM?
- 有没有什么办法可以不传不下载就可以测高的?但是对服务器有某种请求?
答案是 read()
方法必须完成并且 return 可以调用 getHeight()
方法之前的值。
这甚至不是 ImageIO
问题,它只是基本的 Java 语法和语义。
首先,您的问题:
有点。首先,
ImageIO.read(...)
方法是使用所有默认参数解码文件中的 first 图像的便捷方法。由于所有ImageIO.read(...)
操作都委托给特定插件或ImageReader
实例(如JPEGImageReader
),因此此 可能 是特定于插件的。但一般情况下,图像数据被传输和解码"on the fly"。请注意,这里没有 "size calculation",而是 整个图像 在这种情况下被解码为BufferedImage
。必须传输,但不一定存储在计算机上的任何地方,必须传输解码文件中的第一个图像所需的数据,除了解码后的像素值。视情况而定。有一个设置
ImageIO.setUseCache(boolean)
,它控制数据是缓存在磁盘上还是缓存在 RAM 中。- 如果设置为
true
,数据将临时存储在磁盘上,通常在默认的临时目录中(参见java.io.tempdir
系统 属性)。 - 如果设置为
false
,则在解码图像时将数据临时存储在内存中。
- 如果设置为
不,除非你的服务器有一个特殊的 API 来给你这个数据,并且你针对这个 API 执行特定的请求。但是,
ImageIO
API 确实有很多更精细的方法,可以让您更快地获得图像尺寸,而无需 downloading/decoding 整个图像。
获取图像尺寸的更快方法是:
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();
}
}
}
同样,根据图像格式,上述代码应仅读取确定图像尺寸所需的 header/meta 数据。大多数 ImageReader
实现将为此读取所有 header 数据,但与解码整个图像相比,它仍然更快并且涉及的数据(和内存)少得多。
很难对下载或需要下载多少数据做出任何假设,因为不同的格式有不同大小的 header,底层传输(即 HTTP)可能以 "chunks"等