由于使用com.sun.imageio.plugins.jpeg.JPEGImageReader
的颜色配置文件不兼容,我遇到了不支持的图像类型错误。后来,我发现TwelveMonkeys插件被证明可以解决此问题,并在我的项目类路径中引用了相关的.jars。我从TwelveMonkeys github存储库下载了它们。注意我正在使用3.0.2版,因为我正在Java 6上运行JDK 1.6.0_45。这些是我添加到项目中的.jars:
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
我能够使用以下测试来测试该库是否已安装并正常工作:
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。有任何想法吗?更新:
看起来像iTextPDF引起了问题,该问题是项目使用的库。我安装了一个准系统测试应用程序,该程序将CMYK JPEG转换为
BufferedImage
,然后调用ImageIO.read(img)
,它可以正常工作。我正在努力查看为什么当iText处于同一项目和类路径中时,iText在调用ImageIO.read(img)
时找不到TwelveMonkeys插件的原因,但这可能是由于我的知识有限。我还应该补充一点,我正在处理的应用程序是Web服务API的一部分。 最佳答案
通常,当在运行时未从Web应用程序使用ImageIO插件时,原因是未找到服务提供商,因为ImageIO
已被初始化,并且在scanForPlugins()
之前已调用IIORegistry
Web应用程序的库可用于JVM。
从Deploying [ImageIO] plugins in a web app:
由于ImageIO插件注册表(WEB-INF/lib
)是“ VM全局”,因此默认情况下,它不适用于servlet上下文。如果从classes
或ImageIO.scanForPlugins()
文件夹加载插件,这一点尤其明显。除非您在代码中的某处添加scanForPlugins
,否则这些插件可能根本无法使用。
另外,servlet上下文动态地加载和卸载类(每个上下文使用一个新的类加载器)。如果重新启动应用程序,则默认情况下,旧类将永久保留在内存中(因为下次调用ClassLoader
时,它是另一个NullPointerExceptions
扫描/加载类,因此它们将成为注册表中的新实例)。如果尝试使用其余“旧”读取器之一进行读取,则会发生奇怪的异常(例如,访问静态最终初始化字段时为NoClassDefFoundErrors
或未初始化内部类为IIOProviderContextListener
)。
为了解决发现问题和资源泄漏,强烈建议使用IIOProviderContextListener
为Web应用程序实现ImageIO插件的动态加载和卸载。twelvemonkeys-servlet.jar
包含在web.xml
中,并且必须在应用程序的WEB-INF/lib
中注册(如果使用Spring或其他框架,则必须类似)。有关详细信息,请参见上面的链接。
使用上下文侦听器的另一种安全替代方法是将JAR文件放置在应用程序服务器的共享或公用lib文件夹中,而不是Web应用程序中的文件夹。
PS:以上问题/解决方案通常适用于ImageIO插件,而不仅仅是TwelveMonkeys插件。因此,上下文侦听器不依赖于TwelveMonkeys ImageIO插件,并且可以与JAI ImageIO或其他ImageIO插件一起使用。