在没有传输或下载的情况下,Java中是否有任何方法可以获取图像宽度和高度?

时间:2016-03-10 19:54:11

标签: java java-8 bufferedimage javax.imageio

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

我的问题:

  1. 我是否正确理解此方法在尺寸计算之前将图像下载到本地计算机?
  2. 如果是,请将映像的确切位置下载到HDD上的某些JVM缓存中或直接下载到RAM中?
  3. 有没有办法在没有传输或下载的情况下拍摄图像的高度?但是对服务器有某种要求吗?

2 个答案:

答案 0 :(得分:5)

首先,你的问题:

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

  2. 这取决于。有一个设置ImageIO.setUseCache(boolean),用于控制数据是缓存在磁盘上还是缓存在RAM中。

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

  4. 获得图像尺寸的更快方法是:

    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();
             }
        }
     }
    

    同样,根据图像格式,上述代码应该只读取确定图像尺寸所需的标题/元数据。大多数ImageReader实现都会为此读取所有标头数据,但仍然比解码整个图像要快得多,并且涉及的数据(和内存)要少得多。

    很难对下载了多少数据做出任何假设,因为不同的格式具有不同大小的标题,底层传输(即HTTP)可能以“块”等方式传输数据。

答案 1 :(得分:0)

答案是read()方法必须完成并返回一个值,因为可以调用getHeight()方法。

这甚至不是ImageIO问题,它只是基本的Java语法和语义。