7

我有一个简单的服务器端代码,它接收表示 JPEG 格式图像的字节数组并返回图像的尺寸。

public String processImage(byte[] data) {
    long startTime = System.currentTimeMillis();
    ByteArrayInputStream stream = new ByteArrayInputStream(data);
    BufferedImage bufferedImage;
    bufferedImage = ImageIO.read(stream);

    int height = bufferedImage.getHeight();
    int width = bufferedImage.getWidth();

    long endTime = System.currentTimeMillis();

    return "height="+height+" | width="+width+" | elapsed="+(endTime-startTime);
}

它可以工作,但问题是速度慢得让人无法接受。对于 100KB 的图像,需要 6 秒。对于 900KB 的图像,需要 30 秒。这是预期的吗?有没有办法让字节数组到 bufferedImage 的转换更快?

仅供参考,抓住高度/宽度并不是我打算做的唯一事情。我最终想处理缓冲图像。所以获取高度/宽度只是一个示例代码。

4

3 回答 3

7

我认为问题可能与 ImageIO 默认使用磁盘缓存(到临时文件)这一事实有关,即使您的源是ByteArrayInputStream. 因此,如果您的文件系统很慢,无论输入源如何,读取也会很慢。

您可以使用ImageIO.setUseCache(false). 这仍将缓存您的流(以允许向后搜索),但仅在内存中。

ImageIO.setCacheDirectory(cacheDirectory)如果您有更快的磁盘/ramdisk 或类似的磁盘来存储临时文件,也可以使用 将缓存目录设置为特定路径。

也就是说,您报告的读取时间似乎高得不合理,即使对于磁盘缓存读取也是如此。如果问题仍然存在,我建议使用分析器找出时间花在哪里,并查看可能的优化。

PS:如果这真的是问题,我还有一个自定义ByteArrayImageInputStream可能有助于减少磁盘访问和内存消耗。

于 2013-11-22T09:35:23.910 回答
2

您从哪里读取图像?字节[]从哪里来?如果您正在从硬盘读取图像,则使用BufferedInputStream可能有助于读取它。

这可以加快加载速度。但这仅在您从FileInputStream读取时才有帮助。从ByteArrayInputStream读取时,它无济于事。

编辑:您是否可以提供更多信息?字节数组来自哪里?

于 2013-11-21T22:37:11.513 回答
0

尝试使用以下命令行选项运行您的 java 程序,看看它是否能加快速度:

-Djava.awt.headless=true
于 2013-11-21T22:05:54.113 回答