用Java读取逐行编码的9000x9000 JPEG需要1分钟 [英] Reading a progressively encoded 9000x9000 JPEG in Java takes 1 minute

查看:82
本文介绍了用Java读取逐行编码的9000x9000 JPEG需要1分钟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用javax.imageio.ImageIO从磁盘加载高分辨率(9000x9000)JPEG时,在我的scala应用程序中花费了超过1分钟的时间.我尝试创建一个仅Java的项目,但是它仍然耗时太长-大约30秒.

When using javax.imageio.ImageIO to load a large-resolution (9000x9000) JPEG from disk, it takes more than 1 minute in my scala application. I tried creating a Java-only project, but it still takes too long - around 30 seconds.

这是我加载图像的方式:

This is how I load the image:

File file = new File("/Users/the21st/slow2.jpg");
BufferedImage image = ImageIO.read(file);

有什么方法可以提高在Java中读取渐进编码的大尺寸JPEG时的性能吗?

Is there any way to improve performance on reading progressively encoded large-res JPEGs in Java?

有问题的图片为此人(主持人,请不要再次重新上传到其他托管站点,以使编码/质量不变)

The image in question is this one (moderators, please don't reupload to other hosting site again so that encoding / quality doesn't change)

推荐答案

好,这是我到目前为止的发现(老实说,它们有点令人担忧...).

Ok, here's my findings so far (and to be honest, they are a little worrying...).

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

Using the standard JPEG plugin for ImageIO bundled with the Oracle JRE:

BufferedImage image = ImageIO.read(file); 

大约在 18秒内读取计算机(MacBookPro/2.8GHz i7)上的图像.

Reads the image in roughly 18 seconds on my computer (a MacBookPro/2.8GHz i7).

使用我的用于ImageIO的JPEG插件,该插件使用略有不同的代码路径(即,通过获取ImageReader并调用readRaster()方法,然后从中创建一个BufferedImage,可能会获得相同的结果.该代码是不平凡的,因此如果您想查看该代码,请参阅项目页面):

Using my JPEG plugin for ImageIO, which uses a slightly different code path (i.e., you can probably get the same results by obtaining the ImageReader and invoking the readRaster() method, then creating a BufferedImage from that. The code is non-trivial, so please refer tho the project page if you like to see the code):

BufferedImage image = ImageIO.read(file); 

大约在 8秒内读取计算机上的图像.

Reads the image in roughly 8 seconds on my computer.

使用我的 BufferedImageFactory 类和AWT Toolkit:

BufferedImage image = new BufferedImageFactory(Toolkit.getDefaultToolkit().createImage(file.getAbsolutePat‌​h())).getBufferedImage();

〜2.5秒内读取图像.

使用sun.awt.codec中已弃用的JPEGImageDecoder类:

BufferedImage image = new JPEGImageDecoderImpl(new FileInputStream(file)).decodeAsBufferedImage();

〜1.7秒内读取图像.

因此,这意味着即使在Java语言中,我们也应能够在不到2秒的时间内读取该图像.在这种情况下,JPEGImageReader的性能太可笑了,我真的很想知道为什么.如前所述,似乎必须采用渐进式解码,但是它应该比这更好.

So, this means that we should be able to read this image in less than 2 seconds, even in Java. The performance from the JPEGImageReader is just ridiculous in this case, and I really like to know why. As already mentioned, it seems to have to with the progressive decoding, but still, it should be better than this.

更新:

仅出于乐趣,我创建了一个快速的PoC ImageReader插件,该插件由 LibJPEG支持-Turbo Java API .它还不是很完善,但是它允许以下代码:

Just for the fun of it, I created a quick PoC ImageReader plugin backed by the LibJPEG-Turbo Java API. It's not very sophisticated yet, but it allows for code like:

BufferedImage image = ImageIO.read(file); 

要以<在我的计算机上等待1.5秒.

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

PS: I used to maintain ImageIO wrappers for JMagick (similar to the code mentioned by @Jordan Doyle, but it would allow you to program against the ImageIO API), however I stopped as it was too much work. Maybe I have to reconsider... At least it's worth checking out his solution as well, if you don't mind on relying on JNI/native code installation.

这篇关于用Java读取逐行编码的9000x9000 JPEG需要1分钟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆