RenderedImage to BufferedImage for multipage-tiff reading

18,104

Solution 1

Use op1.getAsBufferedImage() to create pg1.

Solution 2

I found a solution at http://www.jguru.com/faq/view.jsp?EID=114602

The first one didn't work, however, the convertRenderedImage function did work.

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;
}

Solution 3

If you are stuck with a RenderedImage, you can use

PlanarImage.wrapRenderedImage(renderedImage).getAsBufferedImage() 

see here for documentation

Solution 4

JAI apparently has a "converter" class in there:

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

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

Share:
18,104
Robert
Author by

Robert

Updated on July 01, 2022

Comments

  • Robert
    Robert almost 2 years

    I am using JAI to load in multipage TIFF images

    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);
    

    However, in the last line I get a runtime error of:

     Exception in thread "main" java.lang.ClassCastException: 
          javax.media.jai.MullOpImage cannot be cast to java.awt.Image
    

    I clear the RenderedImage after attempting to set the BufferedImage so I don't exactly "need" the RenderedImage if there is another method of doing this.

    I attempted:

     pg1.setData(op1.getData());
    

    and that gives an ArrayIndexOutOfBoundsException. I'm not sure why exactly as pg1's width and height are set by op1's, but there is probably a very valid reason.

  • Robert
    Robert almost 13 years
    How do I get to getAsBufferedImage() from RenderedImage?
  • Jeffrey
    Jeffrey almost 13 years
    Don't declare op1 as a RenderedImage, declare it as a NullOpImage, or a PlanarImage.
  • Robert
    Robert almost 13 years
    Ah, okay. I didn't know which object types new NullOpImage could be used with. The PlanarImage version handles it correctly. I didn't notice any difference in speed between it and the convertRenderedImage function I linked to in my answer, but it doesn't require reinventing the wheel and more likely to be optimized.
  • rogerdpack
    rogerdpack almost 8 years
    This brings up an interesting point, BufferedImage "descends" from RenderedImage, so sometimes when you are passing around a RenderedImage, it is actually a BufferedImage. Go figure.