Java RenderImage到BuffereImage用于多页tiff读取
我正在使用JAI加载多页TIFF图像Java RenderImage到BuffereImage用于多页tiff读取,java,jai,Java,Jai,我正在使用JAI加载多页TIFF图像 File file = workArea[0]; SeekableStream s = new FileSeekableStream(file); TIFFDecodeParam param = null; ImageDecoder dec = ImageCodec.createImageDecoder("tiff", s, param); //first page RenderedImage op1 = new NullOpImage(dec
File file = workArea[0];
SeekableStream s = new FileSeekableStream(file);
TIFFDecodeParam param = null;
ImageDecoder dec = ImageCodec.createImageDecoder("tiff", s, param);
//first page
RenderedImage op1 =
new NullOpImage(dec.decodeAsRenderedImage(0),
null,
OpImage.OP_IO_BOUND,
null);
BufferedImage pg1 = new BufferedImage(op1.getWidth(), op1.getHeight(),
BufferedImage.TYPE_INT_RGB);
pg1.getGraphics().drawImage((Image) op1, 0, 0, null);
但是,在最后一行中,我得到一个运行时错误:
Exception in thread "main" java.lang.ClassCastException:
javax.media.jai.MullOpImage cannot be cast to java.awt.Image
我在尝试设置BuffereImage后清除了RenderImage,因此如果有其他方法,我不需要RenderImage
我试图:
pg1.setData(op1.getData());
这就产生了一种ArrayIndexOutOfBoundsException。我不确定为什么pg1的宽度和高度是由op1设置的,但可能有一个非常合理的原因。使用op1。创建pg1。我在
第一个不起作用,但是ConvertRenderImage函数起作用了
public BufferedImage convertRenderedImage(RenderedImage img) {
if (img instanceof BufferedImage) {
return (BufferedImage)img;
}
ColorModel cm = img.getColorModel();
int width = img.getWidth();
int height = img.getHeight();
WritableRaster raster = cm.createCompatibleWritableRaster(width, height);
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
Hashtable properties = new Hashtable();
String[] keys = img.getPropertyNames();
if (keys!=null) {
for (int i = 0; i < keys.length; i++) {
properties.put(keys[i], img.getProperty(keys[i]));
}
}
BufferedImage result = new BufferedImage(cm, raster, isAlphaPremultiplied, properties);
img.copyData(raster);
return result;
}
公共缓冲区图像转换器渲染图像(渲染图像img){
if(img instanceof BuffereImage){
返回(缓冲图像)img;
}
ColorModel cm=img.getColorModel();
int width=img.getWidth();
int height=img.getHeight();
WritableRaster raster=cm.createCompatibleWritableRaster(宽度、高度);
布尔值isAlphaPremultiplied=cm.isAlphaPremultiplied();
Hashtable属性=新的Hashtable();
String[]keys=img.getPropertyNames();
如果(键!=null){
for(int i=0;i
如果您被渲染图像卡住,可以使用
PlanarImage.wrapRenderedImage(renderedImage).getAsBufferedImage()
有关文档,请参见JAI显然有一个“转换器”类:
ImageDecoder dec = ImageCodec.createImageDecoder("PNM", new File(input), null);
return new RenderedImageAdapter(dec.decodeAsRenderedImage()).getAsBufferedImage()
参考:试试这个:
RenderedImage im = dec.decodeAsRenderedImage();
BufferedImage bi = PlanarImage.wrapRenderedImage(im).getAsBufferedImage();
加载TIFF的最简单方法是使用十二猴子和提供插件,以支持将TIFF格式加载到标准Java ImageIO中 只需在Maven依赖项下面添加
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-tiff</artifactId>
<version>3.5</version>
</dependency>
它非常简单和可靠,因为它使用标准的Java ImageIO API进行所有处理
只有来自十二猴子的插件提供SPI插件来支持TIFF
在此添加一个正在运行的示例程序Java 8,它读取TIFF文件并创建一个多页TIFF文件:
BufferedImage b1 = null;
BufferedImage b2 = null;
TIFFImageReaderSpi SPI = new TIFFImageReaderSpi();
ImageReader imageReader1 = SPI.createReaderInstance();
ImageInputStream iis1 = ImageIO.createImageInputStream(new File("1.tif"));
imageReader1.setInput(iis1);
b1 = imageReader1.read(0);
ImageReader imageReader2 = SPI.createReaderInstance();
ImageInputStream iis2 = ImageIO.createImageInputStream(new File("2.tif"));
imageReader2.setInput(iis2);
b2 = imageReader2.read(0);
ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next();
writer.setOutput(ImageIO.createImageOutputStream(new File("3.tif")));
ImageWriteParam writeParam = writer.getDefaultWriteParam();
//writeParam.setTilingMode(ImageWriteParam.MODE_EXPLICIT);
//writeParam.setCompressionType("Deflate");
writer.prepareWriteSequence(null);
IIOImage i1 = new IIOImage(b1, null, null);
IIOImage i2 = new IIOImage(b2, null, null);
writer.writeToSequence(i1, writeParam);
writer.writeToSequence(i2, writeParam);
writer.endWriteSequence();
writer.dispose();
它使用的是Java 8,如果有人想添加压缩,只需注释行并添加适当的压缩名称。如何从RenderImage获取AsBufferedImage()?不要将op1声明为
RenderImage
,将其声明为NullOpImage
或PlanariImage
。啊,好的。我不知道新的NullOpImage可以与哪些对象类型一起使用。PlanarImage版本可以正确处理它。我没有注意到它与我在回答中链接的ConvertRenderImageFunction在速度上有任何差异,但它不需要重新设计轮子,更可能被优化。这带来了一个有趣的点,BufferedImages从RenderImages“下降”,所以有时候当你在一个RenderImages周围经过时,它实际上是一个BuffereImage。如图所示。作为说明,我假设它是在代码的后面,但不要忘记那里有一个s.close
)
BufferedImage b1 = null;
BufferedImage b2 = null;
TIFFImageReaderSpi SPI = new TIFFImageReaderSpi();
ImageReader imageReader1 = SPI.createReaderInstance();
ImageInputStream iis1 = ImageIO.createImageInputStream(new File("1.tif"));
imageReader1.setInput(iis1);
b1 = imageReader1.read(0);
ImageReader imageReader2 = SPI.createReaderInstance();
ImageInputStream iis2 = ImageIO.createImageInputStream(new File("2.tif"));
imageReader2.setInput(iis2);
b2 = imageReader2.read(0);
ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next();
writer.setOutput(ImageIO.createImageOutputStream(new File("3.tif")));
ImageWriteParam writeParam = writer.getDefaultWriteParam();
//writeParam.setTilingMode(ImageWriteParam.MODE_EXPLICIT);
//writeParam.setCompressionType("Deflate");
writer.prepareWriteSequence(null);
IIOImage i1 = new IIOImage(b1, null, null);
IIOImage i2 = new IIOImage(b2, null, null);
writer.writeToSequence(i1, writeParam);
writer.writeToSequence(i2, writeParam);
writer.endWriteSequence();
writer.dispose();