4

我正在使用 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.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

我在尝试设置 BufferedImage 后清除了 RenderedImage,因此如果有另一种方法,我并不完全“需要”RenderedImage。

我尝试过:

 pg1.setData(op1.getData());

这给出了一个 ArrayIndexOutOfBoundsException。我不确定为什么 pg1 的宽度和高度完全由 op1 设置,但可能有一个非常正当的理由。

4

6 回答 6

10

我在http://www.jguru.com/faq/view.jsp?EID=114602找到了解决方案

第一个不起作用,但是 convertRenderedImage 函数确实起作用了。

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;
}
于 2011-08-12T18:35:03.453 回答
4

使用 op1。getAsBufferedImage()创建 pg1。

于 2011-08-12T18:26:43.593 回答
2

如果你被 RenderedImage 卡住了,你可以使用

PlanarImage.wrapRenderedImage(renderedImage).getAsBufferedImage() 

有关文档,请参见此处

于 2016-04-01T04:31:41.700 回答
1

JAI 显然在那里有一个“转换器”类:

ImageDecoder dec = ImageCodec.createImageDecoder("PNM", new File(input), null);
return new RenderedImageAdapter(dec.decodeAsRenderedImage()).getAsBufferedImage()

参考:http ://www.programcreek.com/java-api-examples/index.php?api=com.sun.media.jai.codec.ImageDecoder

于 2016-07-18T19:01:00.393 回答
0

加载 TIFF 的最简单方法是使用带有提供插件的 Twelve Monkey 以支持将 TIFF 格式转换为标准 Java ImageIO。

只需在下面添加 Maven 依赖项,

<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-tiff</artifactId>
<version>3.5</version>
</dependency>

现在,您将能够使用 ImageIO 直接加载 TIFF 文件。

ImageReader imageReader1 = SPI.createReaderInstance();
ImageInputStream iis1 = ImageIO.createImageInputStream(new File("1.tif"));
imageReader1.setInput(iis1);
BufferedImage = imageReader1.read(0); 

它非常简单可靠,因为它使用标准 Java ImageIO API 进行所有处理。

只有 Twelve Monkey 的 Plugin 提供了 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,如果有人想添加压缩,只需注释该行并添加适当的压缩名称。

于 2020-06-01T13:04:15.080 回答
0

尝试这个 :

   RenderedImage im =  dec.decodeAsRenderedImage();
   BufferedImage bi = PlanarImage.wrapRenderedImage(im).getAsBufferedImage();
于 2018-01-30T10:12:00.780 回答