字节数组缓冲图像转换速度慢

时间:2013-11-21 22:03:44

标签: java bufferedimage javax.imageio bytearrayinputstream

我有一个简单的服务器端代码,它接收一个表示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的图像,它需要6s。对于900KB的图像,它需要30秒。这是预期的吗?有没有办法让字节数组更快地进行bufferedImage转换?

仅供参考,抓住身高/宽度不是我打算做的唯一事情。我最终想要处理bufferedImage。所以获得高度/宽度只是一个示例代码。

3 个答案:

答案 0 :(得分:7)

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

您可以使用ImageIO.setUseCache(false)禁用磁盘缓存(以使用更多内存为代价)。这仍将缓存您的流(允许向后搜索),但仅限于内存。

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

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

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

答案 1 :(得分:2)

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

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

编辑:您可以提供更多信息吗?字节数组来自何处?

答案 2 :(得分:0)

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

-Djava.awt.headless=true