在Java中读取逐行编码的9000x9000 JPEG需要1分钟

the*_*1st 10 java jpeg javax.imageio

javax.imageio.ImageIO用于从磁盘加载大分辨率(9000x9000)JPEG时,我的scala应用程序需要1分钟以上.我尝试创建一个仅限Java的项目,但它仍然需要很长时间 - 大约30秒.

这是我加载图像的方式:

File file = new File("/Users/the21st/slow2.jpg");
BufferedImage image = ImageIO.read(file);
Run Code Online (Sandbox Code Playgroud)

有没有办法提高在Java中逐步编码的大分辨率JPEG读取的性能?

有问题的图片是这个(版主,请不要再次重新上传到其他托管网站,以便编码/质量不会改变)

har*_*ldK 6

好的,这是我迄今为止的调查结果(说实话,他们有点担心......).

使用与Oracle JRE捆绑在一起的ImageIO的标准JPEG插件:

BufferedImage image = ImageIO.read(file); 
Run Code Online (Sandbox Code Playgroud)

在我的电脑上大约18秒钟读取图像(MacBookPro/2.8GHz i7).

使用我的ImageIO插件,它使用稍微不同的代码路径(也就是说,你可以通过获取ImageReader和调用readRaster()方法获得相同的结果,然后BufferedImage从中创建一个.代码是非平凡的,所以请参考项目页面,如果你想看代码):

BufferedImage image = ImageIO.read(file); 
Run Code Online (Sandbox Code Playgroud)

在我的电脑上大约8秒钟读取图像.

使用我的BufferedImageFactory班级和AWT Toolkit:

BufferedImage image = new BufferedImageFactory(Toolkit.getDefaultToolkit().createImage(file.getAbsolutePat??h())).getBufferedImage();
Run Code Online (Sandbox Code Playgroud)

在我的计算机上~2.5秒内读取图像.

使用以下的弃用JPEGImageDecodersun.awt.codec:

BufferedImage image = new JPEGImageDecoderImpl(new FileInputStream(file)).decodeAsBufferedImage();
Run Code Online (Sandbox Code Playgroud)

在我的电脑上读取图像约1.7秒.

因此,这意味着我们应该能够在不到2秒的时间内读取此图像,即使在Java中也是如此.JPEGImageReader在这种情况下,来自的表现是荒谬的,我真的很想知道为什么.如前所述,似乎必须采用逐行解码,但仍然应该比这更好.

更新:

为了好玩,我创建了一个ImageReaderLibJPEG-Turbo Java API支持的快速PoC 插件.它还不是很复杂,但它允许代码如下:

BufferedImage image = ImageIO.read(file); 
Run Code Online (Sandbox Code Playgroud)

在我的计算机上<1.5秒内读取图像.

PS:我曾经为JMagick维护ImageIO包装器(类似于@Jordan Doyle提到的代码,但是它允许你对ImageIO API进行编程),但是因为工作太多而停止了.也许我必须重新考虑......如果您不介意依赖JNI /本机代码安装,至少值得检查一下他的解决方案.