java - Java中有什么方法可以在不传输或下载的情况下获取图像的宽度和高度?

标签 java java-8 bufferedimage javax.imageio

为了获得图像的高度,我们可以使用 ImageIO.read(new URL("…")).getHeight() .

我的问题:

  1. 我是否正确理解此方法会先将图像下载到本地计算机再进行大小计算?

  2. 如果是,图像下载到的确切位置——HDD 上的某些 JVM 缓存还是直接下载到 RAM?

  3. 有什么方法可以在不传输或下载的情况下获取图像的高度?但是对服务器有某种请求?

最佳答案

首先,您的问题:

  1. 有点。首先,ImageIO.read(...) 方法是使用所有默认解码参数对文件中的第一个 图像进行解码的便捷方法。由于所有 ImageIO.read(...) 操作都被委托(delegate)来格式化特定插件或 ImageReader 实例(如 JPEGImageReader),这 可能 是特定于插件的。但一般情况下,图像数据是“即时”传输和解码的。请注意,这里没有“大小计算”,而是在这种情况下将整个图像 解码为BufferedImage。必须传输解码文件中第一张图像所需的数据,但不一定存储在计算机上的任何位置,解码像素值除外。

  2. 视情况而定。有一个设置 ImageIO.setUseCache(boolean),它控制数据是缓存在磁盘上还是缓存在 RAM 中。

    • 如果设置为 true,则数据临时存储在磁盘上,通常存储在默认的临时目录中(请参阅 java.io.tempdir 系统属性)。
    • 如果设置为 false,则在解码图像时将数据临时存储在内存中。
  3. 不,除非您的服务器有一个特殊的 API 来为您提供这些数据,并且您对这个 API 执行特定的请求。然而,ImageIO API 确实有很多更精细的方法,可以让您更快地获得图像尺寸,而无需预先下载/解码整个图像。

获取图像尺寸的更快方法是:

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 /元数据。大多数 ImageReader 实现将为此读取所有 header 数据,但与解码整个图像相比,它仍然更快并且涉及的数据(和内存)少得多。

很难对下载或需要下载多少数据做出任何假设,因为不同的格式具有不同大小的 header ,底层传输(即 HTTP)可能以“ block ”等形式传输数据。

关于java - Java中有什么方法可以在不传输或下载的情况下获取图像的宽度和高度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35925981/

相关文章:

java - 如何将Bufferedimage转换为索引类型,然后提取argb调色板

Java RestFul Web 服务 : JAX-RS implementation with Jersey 2. 3.1 库

java - 如何更好地处理两个 JAR 中的相同类

java - 如何使用流获取数组列表的特定值

java - 如何流式传输和映射一对多关系?

java - Mapstruct:更新集合中的各个模型

java - 将一系列 BufferedImages 转换为 Java 中的视频?

java - 非通用子类继承(实现)通用父类(super class)(接口(interface))

java - CMIS 浏览器网络应用程序

java - 如何更改从文件加载的 BufferedImage 的图像类型?