Reading pixel from large jp2 image without loading the whole image into memory

I am trying to read parts from a large image in java. My image is over 700MB in size. I used this code, which usually reads pixels without loading the whole image into memory:

Rectangle sourceRegion = new Rectangle(0, 0, 512, 512); // The region you want to extract

ImageInputStream stream = ImageIO.createImageInputStream( new File("/home/dhoha/Downloads/BreastCancer.jp2")); // File or input stream
final Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);

if (readers.hasNext()) {
ImageReader reader = (ImageReader)readers.next();

reader.setInput(stream, true);

ImageReadParam param = reader.getDefaultReadParam();
param.setSourceRegion(sourceRegion); // Set region

BufferedImage image = reader.read(0, param); // Will read only the region specified

      

However, I got the error:

Exception in thread "main" java.lang.IllegalArgumentException: Dimensions (width=95168 height=154832) are too large
    at java.awt.image.SampleModel.<init>(SampleModel.java:130)
    at java.awt.image.ComponentSampleModel.<init>(ComponentSampleModel.java:146)
    at java.awt.image.PixelInterleavedSampleModel.<init>(PixelInterleavedSampleModel.java:87)
    at com.sun.media.imageioimpl.plugins.jpeg2000.J2KRenderedImageCodecLib.createSampleModel(J2KRenderedImageCodecLib.java:741)
    at com.sun.media.imageioimpl.plugins.jpeg2000.J2KRenderedImageCodecLib.createOriginalSampleModel(J2KRenderedImageCodecLib.java:729)
    at com.sun.media.imageioimpl.plugins.jpeg2000.J2KRenderedImageCodecLib.<init>(J2KRenderedImageCodecLib.java:261)
    at com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageReaderCodecLib.read(J2KImageReaderCodecLib.java:364)
    at testJai2.test3.main(test3.java:21)

      

Any help please read parts of this large image?

+2


source to share


1 answer


There are various ways to load parts of an image into memory and then process them. You can try the following method for reading snippets:

public static BufferedImage readFragment(InputStream stream, Rectangle rect)
            throws IOException {
        ImageInputStream imageStream = ImageIO.createImageInputStream(stream);
        ImageReader reader = ImageIO.getImageReaders(imageStream).next();
        ImageReadParam param = reader.getDefaultReadParam();

        param.setSourceRegion(rect);
        reader.setInput(imageStream, true, true);
        BufferedImage image = reader.read(0, param);

        reader.dispose();
        imageStream.close();

        return image;
}

      

And calling it like this:

URL url = new URL("..."); // You can use your own stream instead of URL
Image chunk = readFragment(url.openStream(), new Rectangle(150, 150, 300, 250));

      



This is marked as the correct answer in this thread.

You can use this technique to finally read the entire image into memory if you need to do some simple calculations.

EDIT: The
resolution of the image you are trying to process is greater than the array can have (95168x154832). This way you won't be able to read the image as it is ImageIO.createImageInputStream()

trying to load the entire image into an array AFAIK.

What you can do is use a library named ImgLib2

. Here you can find some examples. ImgLib2

uses multidimensional arrays to read (big) image data and therefore can handle more than ImageIO

.

0


source







All Articles