ImageIO 不支持的图像类型 - 修复了 TwelveMonkeys 插件不起作用? [英] ImageIO Unsupported Image Type - TwelveMonkeys Plugin with fix not working?

查看:80
本文介绍了ImageIO 不支持的图像类型 - 修复了 TwelveMonkeys 插件不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于使用 com.sun.imageio.plugins.jpeg.JPEGImageReader 的颜色配置文件不兼容,我遇到了不支持的图像类型错误.后来我找到了 TwelveMonkeys 插件,这些插件被证明可以解决这个问题,并且在我的项目类路径中引用了依赖的 .jars.我从 TwelveMonkeys github 存储库下载了它们.请注意,我使用的是 3.0.2 版,因为我在使用 JDK 1.6.0_45 的 Java 6 上运行.这些是我添加到我的项目中的 .jars:

I encountered the Unsupported Image Type error due to an incompatible colour profile using com.sun.imageio.plugins.jpeg.JPEGImageReader. I later found the TwelveMonkeys plugins that are proven to fix this issue and have referenced the dependent .jars in my project classpath. I downloaded them from the TwelveMonkeys github repository. Note i'm using version 3.0.2 because I'm running on Java 6 with JDK 1.6.0_45. These are the .jars I've added to my project:

common-lang-3.0.2.jar
common-io-3.0.2.jar
common-image-3.0.2.jar
imageio-core-3.0.2.jar
imageio-metadata-3.0.2.jar
imageio-jpeg-3.0.2.jar

我能够使用以下测试来测试库是否安装和工作:

I was able to test the library is installed and working using the following test:

Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("JPEG");
while (readers.hasNext()) {
    System.out.println("reader: " + readers.next());
}

输出:

reader: com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader@4102799c
reader: com.sun.imageio.plugins.jpeg.JPEGImageReader@33d6f122

当我运行我的代码时,它仍在尝试使用 com.sun.imageio.plugins.jpeg.JPEGImageReader 读取 JPEG 并继续抛出 IIOException.有什么想法吗?

When i run my code, it is still trying to read the JPEG with com.sun.imageio.plugins.jpeg.JPEGImageReader and continues to throw the IIOException. Any ideas?

更新:它看起来像 iTextPDF 导致了项目使用的库的问题.我设置了一个准系统测试应用程序,它将 CMYK JPEG 转换为 BufferedImage,然后调用 ImageIO.read(img) 并且它工作正常.我正在努力找出为什么 iText 在调用 ImageIO.read(img) 时找不到 TwelveMonkeys 插件的原因,因为它们在同一个项目和类路径中,但这可能是由于我有限的知识.我还应该补充一点,我正在处理的应用程序是 Web 服务 API 的一部分.

UPDATE: Its looking like iTextPDF is causing the issue which is a library used by the project. I setup a barebone test application that converts a CMYK JPEG to a BufferedImage and then calls ImageIO.read(img) and it works fine. I'm struggling to see a reason why iText wouldn't be finding the TwelveMonkeys plugin when it calls ImageIO.read(img) when they're in the same project and classpath, but that's probably due to my limited knowledge. I should also add that the application i'm working on is part of a web service API.

推荐答案

通常情况下,当 Web 应用程序在运行时未使用 ImageIO 插件时,原因是服务提供者未发现是因为 ImageIO 已经初始化,并且在 Web 应用程序的库可用于 JVM 之前调用了 scanForPlugins().

As often is the case, when an ImageIO plugin isn't used at run-time from a web application, the cause is that the service provider isn't found because ImageIO is already initialized, and has invoked scanForPlugins() before the web app's libraries were available to the JVM.

来自 在网络中部署 [ImageIO] 插件应用:

因为 ImageIO 插件注册表(IIORegistry)是VM 全局",所以默认情况下它不适用于 servlet 上下文.如果您从 WEB-INF/libclasses 文件夹加载插件,这一点尤其明显.除非您在代码中的某处添加 ImageIO.scanForPlugins(),否则这些插件可能根本不可用.

Because the ImageIO plugin registry (the IIORegistry) is "VM global", it doesn't by default work well with servlet contexts. This is especially evident if you load plugins from the WEB-INF/lib or classes folder. Unless you add ImageIO.scanForPlugins() somewhere in your code, the plugins might never be available at all.

此外,servlet 上下文动态加载和卸载类(每个上下文使用新的类加载器).如果您重新启动应用程序,默认情况下旧类将永远保留在内存中(因为下次调用 scanForPlugins 时,将是另一个扫描/加载类的 ClassLoader,因此它们将是注册表中的新实例).如果尝试使用剩余的旧"数据之一进行读取.读者,可能会发生奇怪的异常(例如访问静态最终初始化字段时的 NullPointerExceptions 或未初始化内部类的 NoClassDefFoundErrors).

In addition, servlet contexts dynamically loads and unloads classes (using a new class loader per context). If you restart your application, old classes will by default remain in memory forever (because the next time scanForPlugins is called, it's another ClassLoader that scans/loads classes, and thus they will be new instances in the registry). If a read is attempted using one of the remaining "old" readers, weird exceptions (like NullPointerExceptions when accessing static final initialized fields or NoClassDefFoundErrors for uninitialized inner classes) may occur.

为了同时解决发现问题和资源泄漏,强烈建议使用IIOProviderContextListener,它实现了Web应用程序ImageIO插件的动态加载和卸载.

To work around both the discovery problem and the resource leak, it is strongly recommended to use the IIOProviderContextListener that implements dynamic loading and unloading of ImageIO plugins for web applications.

IIOProviderContextListener 包含在 twelvemonkeys-servlet.jar 中,并且必须在您的应用程序的 web.xml 中注册(或类似的,如果使用 Spring 或其他框架).详情请见上面的链接.

The IIOProviderContextListener is contained in the twelvemonkeys-servlet.jar, and must be registered in your application's web.xml (or similar if using Spring or other framework). See the above link for details.

使用上下文侦听器的另一种安全替代方法是将 JAR 文件放在应用程序服务器的共享或公共 lib 文件夹中,而不是放在 Web 应用程序内的 WEB-INF/lib 文件夹中.

Another safe alternative to using the context listener, is to place the JAR files in the application server's shared or common lib folder, instead of the WEB-INF/lib folder inside your web application.

PS:上述问题/解决方案一般适用于 ImageIO 插件,而不仅仅是 TwelveMonkeys 插件.因此,上下文侦听器与 TwelveMonkeys ImageIO 插件无关,也可以与 JAI ImageIO 或其他 ImageIO 插件一起使用.

PS: The above problem/solution applies to ImageIO plugins in general, not just the TwelveMonkeys plugins. Because of this, the context listener has no dependencies to the TwelveMonkeys ImageIO plugins, and may be used with JAI ImageIO or other ImageIO plugins as well.

这篇关于ImageIO 不支持的图像类型 - 修复了 TwelveMonkeys 插件不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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