如何将 TIFF ImageReader 添加到 Grails 中注册的那些 [英] How to add TIFF ImageReader to those registered in Grails

查看:21
本文介绍了如何将 TIFF ImageReader 添加到 Grails 中注册的那些的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个 Grails 应用程序,该应用程序可以显示 TIFF 文件和其他图像的预览.

背景

图像是从 SOAP 服务构建的,该服务为我提供图像的字节数.在服务方法中,我获取 byte[],从中构造一个 ByteArrayInputStream,然后从中创建一个 BufferedImage.

def inputStream = new ByteArrayInputStream(bytes)BufferedImage originalImage = ImageIO.read(inputStream)ImageIO.write(originalImage, 'png', response.outputStream)

对于 JPG,我可以通过这种方式轻松地将图像作为 img 标签的 src 流式传输到浏览器.但是,TIFF 需要将图像转换为其他格式(最好是 JPG 或 PNG)以使其成为标签的 src.

问题

我知道 我需要 JAI 才能读取 TIFF 文件.jai_core.jar、jai_codec.jar 文件在我的类路径中.事实上,因为我使用的是 Mac OSX,它们是自动安装的.但是,当我运行 grails 应用程序并尝试根据从 SOAP 服务接收到的字节构建 TIFF 图像时,我收到此错误:

<代码>|错误 2013-06-18 15:23:38,135 [http-bio-8080-exec-10] 错误 errors.GrailsExceptionResolver - 处理请求时发生 IllegalArgumentException:[GET]/BDMPlugin/BDMPlugin/displayImageFromRef - 参数:页面参考:28:22072FBCA0A8889D9C041D76A588BCF4DCB40376A23B5FD5C301378C8E66EB9F4933A5DFCA46365F927D9E91B337B6E44E4E680000类型:TIFF我 == 空!.堆栈跟踪如下:消息:im == null!线|方法->>第1457章写入 javax.imageio.ImageIO- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|1571 |写进     ''|28 |edu.missouristate.bdmplugin.ImageService 中的 writeImageToResponse|44 |'' 中的 bytesToPng|39 |edu.missouristate.bdmplugin.BDMPluginController 中的 displayImageFromRef|第895话java.util.concurrent.ThreadPoolExecutor$Worker 中的 runTask|918 |跑 ........在     ''^ 680 |在 java.lang.Thread 中运行

我尝试了以下 脚本 来确定安装了哪些图像阅读器:

IIORegistry reg = IIORegistry.getDefaultInstance();迭代器 spIt = reg.getServiceProviders(ImageReaderSpi.class, false);spIt.each(){println it.getVendorName() <<"|"<<it.getVersion() <<"|<<it.getDescription() ;}

输出如下:

Sun Microsystems, Inc. |1.0 |标准 BMP 图像阅读器Sun Microsystems, Inc. |1.0 |标准 GIF 图片阅读器Sun Microsystems, Inc. |1.0 |标准 WBMP 图像阅读器Sun Microsystems, Inc. |1.0 |标准 PNG 图像阅读器Sun Microsystems, Inc. |0.5 |标准 JPEG 图像阅读器

但是,如果我在 Groovy 控制台中运行相同的 Groovy 脚本,则会得到以下输出:

Sun Microsystems, Inc. |0.5 |标准 JPEG 图像阅读器Sun Microsystems, Inc. |1.0 |标准 BMP 图像阅读器Sun Microsystems, Inc. |1.0 |标准 WBMP 图像阅读器Sun Microsystems, Inc. |1.0 |标准 PNG 图像阅读器Sun Microsystems, Inc. |1.0 |标准 GIF 图片阅读器苹果电脑公司|1.0 |标准 TIFF 图像阅读器

同一组阅读器,但还包括 Apple 的 TIFF 阅读器.为什么 GroovyConsole 能够找到它而不是我的 Grails 环境,即使它们都使用相同的 JRE?有没有一种方法可以通过 import com.sun.media.jaicom.sun.media.imageio.plugins.tiff 的一些导入手动添加 TIFF 阅读器?

我尝试将 TIFFImageReaderSpi 的手动注册添加到我的服务方法中:

import com.sun.imageio.plugins.tiff.TIFFImageReaderSpi...IIORegistry reg = IIORegistry.getDefaultInstance()reg.registerServiceProvider(新的TIFFImageReaderSpi())

originalImage 变量仍然返回 null.

解决方案

所以问题似乎有几层.

首先,import com.sun.imageio.plugins.tiff.TIFFImageReaderSpi 语句正在导入 Apple TIFF 阅读器,这显然无法完成阅读我的 TIFF 的工作.>

真正需要的是import com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi,但这给我带来了几个不同的错误;别担心,我能够修复它们.:)

首先,导入没有解决.为了获得 com.sun.media.imageioimpl 包,我从 https 获得了捆绑 JAI 的源代码://github.com/stain/jai-imageio-core.我将其导入 Eclipse,然后使用 Eclipse 的导出工具构建了一个 JAR.我把它放在我的项目的 lib 文件夹中,但导入仍然没有解决.我必须手动将该 jar 添加到我的项目的类路径中,然后导入才能解决.

其次,当我运行应用程序时,我会收到此错误:

<代码>|错误 2013-06-19 11:15:27,665 [http-bio-8080-exec-3] 错误 errors.GrailsExceptionResolver - 处理请求时发生 IllegalArgumentException:[GET]/pluginproject/Controller/action - 参数:供应商名称 == 空!.堆栈跟踪如下:消息:vendorName == null!线|方法->>59 |<初始化>在 javax.imageio.spi.IIOServiceProvider 中- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|第214话<初始化>在 javax.imageio.spi.ImageReaderWriterSpi|192 |<初始化>......在 javax.imageio.spi.ImageReaderSpi|88 |<初始化>在 com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi|31 |字节到PNG....在 edu.mystateu.pluginproject.ImageService

供应商名称 == 空?幸运的是,我找到了这个问题/答案.

在为 jai-imageio-core 创建 jar 文件时,我必须手动指定清单文件的位置,而不是让 Eclipse 生成一个新的空白文件.清单文件位于/jai-imageio-core/src/main/resources/META-INF/MANIFEST.MF,一旦我指定使用该文件,导入的库就会解析并读取我的图像.

最后,服务方法的代码非常好.我只需要真正将 JAI 正确导入到我的项目中.非常感谢@haraldK,他的反馈让我走上了正轨.

I'm trying to create a Grails application that can display previews of TIFF files, and other images as well.

Background

The images are constructed from a SOAP service that gives me the bytes of the image. In a service method, I take the byte[], construct a ByteArrayInputStream from it, and then create a BufferedImage from that.

def inputStream = new ByteArrayInputStream(bytes)
BufferedImage originalImage = ImageIO.read(inputStream)
ImageIO.write(originalImage, 'png', response.outputStream)

For JPGs, I can easily stream the images to the browser this way as the src of an img tag. TIFFs, though, I'd need to convert the images into some other format (preferably JPG or PNG) to make them the src of an tag.

The Problem

I know that I need JAI in order to read the TIFF files. The jai_core.jar, jai_codec.jar files are in my classpath. In fact, because I'm on Mac OSX, they're installed automatically. However, when I run the grails application and it tries to construct a TIFF image from the bytes received from the SOAP service, I get this error:

| Error 2013-06-18 15:23:38,135 [http-bio-8080-exec-10] ERROR errors.GrailsExceptionResolver  - IllegalArgumentException occurred when processing request: [GET] /BDMPlugin/BDMPlugin/displayImageFromRef - parameters:
pageRef: 28:22072FBCA0A8889D9C041D76A588BCF4DCB40376A23B5FD5C301378C8E66EB9F4933A5DFCA46365F927D9E91B337B6E1E980FB4406644801
type: TIFF
im == null!. Stacktrace follows:
Message: im == null!
    Line | Method
->> 1457 | write                in javax.imageio.ImageIO
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1571 | write                in     ''
|     28 | writeImageToResponse in edu.missouristate.bdmplugin.ImageService
|     44 | bytesToPng           in     ''
|     39 | displayImageFromRef  in edu.missouristate.bdmplugin.BDMPluginController
|    895 | runTask              in java.util.concurrent.ThreadPoolExecutor$Worker
|    918 | run . . . . . . . .  in     ''
^    680 | run                  in java.lang.Thread

I tried the following script to figure out which image readers were installed:

IIORegistry reg = IIORegistry.getDefaultInstance();
Iterator spIt = reg.getServiceProviders(ImageReaderSpi.class, false);
spIt.each(){
println it.getVendorName() << " | " << it.getVersion() << " | "<< it.getDescription() ;
}

This outputs the following:

Sun Microsystems, Inc. | 1.0 | Standard BMP Image Reader
Sun Microsystems, Inc. | 1.0 | Standard GIF image reader
Sun Microsystems, Inc. | 1.0 | Standard WBMP Image Reader
Sun Microsystems, Inc. | 1.0 | Standard PNG image reader
Sun Microsystems, Inc. | 0.5 | Standard JPEG Image Reader

However, if I run that same Groovy script in the Groovy Console, I get this output:

Sun Microsystems, Inc. | 0.5 | Standard JPEG Image Reader
Sun Microsystems, Inc. | 1.0 | Standard BMP Image Reader
Sun Microsystems, Inc. | 1.0 | Standard WBMP Image Reader
Sun Microsystems, Inc. | 1.0 | Standard PNG image reader
Sun Microsystems, Inc. | 1.0 | Standard GIF image reader
Apple computer Inc. | 1.0 | Standard TIFF image reader

Same set of readers, but it also includes Apple's TIFF reader. Why is the GroovyConsole able to find it and not my Grails environment, even though they're both using the same JRE? Is there a way that I can manually add the TIFF reader via some import from import com.sun.media.jai or com.sun.media.imageio.plugins.tiff?

I tried adding a manual registration of the TIFFImageReaderSpi to my service method:

import com.sun.imageio.plugins.tiff.TIFFImageReaderSpi
...
IIORegistry reg = IIORegistry.getDefaultInstance()
reg.registerServiceProvider(new TIFFImageReaderSpi())

The originalImage variable still comes back null.

解决方案

So there seem to have been a couple layers to the problem.

First, the import com.sun.imageio.plugins.tiff.TIFFImageReaderSpi statement was importing the Apple TIFF reader, which apparently just wasn't up to the job of reading my TIFF.

What I really needed was import com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi, but that presented me with a couple of different errors; don't worry, I was able to fix them. :)

First, the import wasn't resolving. To get the com.sun.media.imageioimpl package, I got the source for a bundled JAI from https://github.com/stain/jai-imageio-core. I imported that into Eclipse, then built a JAR using Eclipse's Export tool. This I placed in my project's lib folder, but the import still wasn't resolving. I had to manually add that jar to my project's classpath, and then the import would resolve.

Second, when I ran the app, I'd get this error:

| Error 2013-06-19 11:15:27,665 [http-bio-8080-exec-3] ERROR errors.GrailsExceptionResolver  - IllegalArgumentException occurred when processing request: [GET] /pluginproject/Controller/action - parameters:
vendorName == null!. Stacktrace follows:
Message: vendorName == null!
   Line | Method
->>  59 | <init>              in javax.imageio.spi.IIOServiceProvider
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   214 | <init>              in javax.imageio.spi.ImageReaderWriterSpi
|   192 | <init> . . . . . .  in javax.imageio.spi.ImageReaderSpi
|    88 | <init>              in com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi
|    31 | bytesToPng . . . .  in edu.mystateu.pluginproject.ImageService

vendorName == null? Fortunately, I found this question/answer.

When creating the jar file for jai-imageio-core, I had to manually specify the location of the manifest file, rather than letting Eclipse generate a new blank one. The manifest file was located in /jai-imageio-core/src/main/resources/META-INF/MANIFEST.MF, and once I specified to use that one, the imported lib resolved and read my image.

In the end, the service method's code was perfectly fine. I just needed to actually get JAI imported into my project correctly. Thanks very much to @haraldK, whose feedback got me on the right track.

这篇关于如何将 TIFF ImageReader 添加到 Grails 中注册的那些的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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