0

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

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

当我运行我的代码时,它仍在尝试读取 JPEGcom.sun.imageio.plugins.jpeg.JPEGImageReader并继续抛出 IIOException。有任何想法吗?

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

4

2 回答 2

3

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

在 Web 应用程序中部署 [ImageIO] 插件

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

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

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

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

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

PS:上述问题/解决方案通常适用于 ImageIO 插件,而不仅仅是 TwelveMonkeys 插件。因此,上下文监听器不依赖于 TwelveMonkeys ImageIO 插件,也可以与 JAI ImageIO 或其他 ImageIO 插件一起使用。

于 2018-03-16T14:20:59.707 回答
0

对于没有 web.xml 的 Spring Boot 应用程序,您需要IIOProviderContextListener@SpringBootApplication应该扩展的类中注册SpringBootServletInitializer

@Override
    public void onStartup(final ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
        // Register the listener from Twelvemonkeys to support CMYK image handling with ImageIO
        servletContext.addListener(IIOProviderContextListener.class);
    }

另请参阅此问题,其中对此进行了更详细的解释。

于 2021-04-26T07:21:48.180 回答