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

これを試して :

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

TIFFをロードする最も簡単な方法は、標準JavaImageIOへのTIFF形式をサポートするプラグインを提供するTwelveMonkeyを使用することです。

以下に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); 

すべての処理に標準のJavaImageIOAPIを使用するため、非常に簡単で信頼性があります。

TIFFのサポートを提供するSPIプラグインを提供するのは、TwelveMonkeyのプラグインのみです。

ここに、実行中のサンプルプログラムの1つを追加します。これは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 に答える