热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

如何从ImageIO中排除特

这里的问题是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 registry
IIORegistry registry = IIORegistry.getDefaultInstance();
// Lookup the known TIFF providers
ImageReaderSpi 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 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 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 decoded
}
catch (Exception e) {
// TODO: Log exception?
e.printStackTrace();
// Reading failed, try the next Reader
inputStream.seek(0);
}
finally {
reader.dispose();
}
}
}

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





推荐阅读
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了作者在开发过程中遇到的问题,即播放框架内容安全策略设置不起作用的错误。作者通过使用编译时依赖注入的方式解决了这个问题,并分享了解决方案。文章详细描述了问题的出现情况、错误输出内容以及解决方案的具体步骤。如果你也遇到了类似的问题,本文可能对你有一定的参考价值。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • centos安装Mysql的方法及步骤详解
    本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
author-avatar
Idi-amin_643
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有