栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何从ImageIO中排除特定的TIFF阅读器?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何从ImageIO中排除特定的TIFF阅读器?

这里的问题是ImageIO使用服务提供商接口(SPI)查找在运行时注册插件,并且在您的设置中找到了多个可以读取TIFF的插件。默认情况下,这些插件没有特定的顺序,这就是为什么有时您首先获得

com.sun
(JAI)TIFF插件,而有时首先获得
it.geosolutions
(Geosolutions)TIFF插件的原因。
ImageIO.read(...)
只会尝试第一个插件,如果失败则放弃。

如果可以的话,最简单的解决方案是从类路径中删除其中一个插件。但是我想你已经想到了这一点。还有许多其他方法可以解决此问题(我用Java给出了代码示例,因为这是我最熟悉的示例,因此我相信您可以在Scala中将其编写得更优雅;-)。

需要对代码进行最少更改的一种方法是在运行时注销“引导”代码中某处的JAI提供程序(确切的位置取决于应用程序,可能是静态初始化程序块或Web上下文侦听器,或者类似)。该

IIORegistry
有一个
deregisterServiceProvider
用于此目的的方法,去除从注册表中供应商,使其不能用于
ImageIO

另一种选择是为提供者定义明确的顺序。如果出于某种原因(第三方要求/插件间的依存关系等)需要以单一格式拥有多个提供程序,这将很有用。该

IIORegistry
有一个
setOrdering
用于此目的,即允许设置方法
成对 两个服务提供商的排序,使得
ImageIO
总是喜欢一个先于另一个。

下面的代码显示了以上两个选项:

// Get the global registryIIORegistry registry = IIORegistry.getDefaultInstance();// Lookup the known TIFF providersImageReaderSpi jaiProvider = lookupProviderByName(registry, "com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi");ImageReaderSpi geoProvider = lookupProviderByName(registry, "it.geosolutions.imageioimpl.plugins.tiff.TIFFImageReaderSpi");if (jaiProvider != null && geoProvider != null) {    // If both are found, EITHER    // order the it.geosolutions provider BEFORE the com.sun (JAI) provider    registry.setOrdering(ImageReaderSpi.class, geoProvider, jaiProvider);    // OR    // un-register the JAI provider    registry.deregisterServiceProvider(jaiProvider);}

// New and improved (shorter) version. :-)private static <T> T lookupProviderByName(final ServiceRegistry registry, final String providerClassName) {    try {        return (T) registry.getServiceProviderByClass(Class.forName(providerClassName));    }    catch (ClassNotFoundException ignore) {        return null;    }}

上面的代码将确保Geosolutions
TIFF插件将始终由所使用

ImageIO.read(...)
,并且您现有的代码应该可以正常工作(但现在很稳定)。

一个完全不同的选择是尝试使用所有已注册的TIFF插件读取数据,并使用第一个成功的插件。这比以前的代码更明确,但是需要重写图像读取代码:

byte[] data;BufferedImage image;try (ImageInputStream inputStream = ImageIO.createImageInputStream(new ByteArrayInputStream(data))) {    Iterator<ImageReader> readers = ImageIO.getImageReaders(inputStream);    // Try reading the data, using each reader until we succeed (or have no more readers)    while (readers.hasNext()) {        ImageReader reader = readers.next();        try { reader.setInput(inputStream); image = reader.read(0); break; // Image is now correctly depred        }        catch (Exception e) { // TODO: Log exception? e.printStackTrace(); // Reading failed, try the next Reader inputStream.seek(0);        }        finally { reader.dispose();        }    }}

当然,您可以组合使用以上选项,以兼顾两个方面的优势(即,如果一个阅读器出现故障,则订单稳定且回退)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/463763.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号