从大的jp2图像读取像素,而不将整个图像加载到内存中 [英] Read pixel from a big jp2 image without loading the whole image into memory

查看:541
本文介绍了从大的jp2图像读取像素,而不将整个图像加载到内存中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从java中的大图像中读取部分。我的图像大小超过700 MB。我使用了这个代码,通常读取像素而不将整个图像加载到内存中:

I'm trying to read parts from a big image in java. My image size is more than 700 MB. I have used this code which normally 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

然而,我收到错误:

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 to read parts from this big image?

推荐答案

有多种方法可以将部分图像加载到内存中然后处理它。您可以尝试以下方法来读取片段:

There are different ways to load parts of image to memory and then process it afterwards. You can try out the following method to read fragments:

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

并且这样称呼:

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

这在这个主题。

你如果你需要做一些简单的计算,可以使用这种技术最终将整个图像读入内存。

You can use this technique to finally read the whole image into the memory if you need by doing some simple calculations.

编辑:

您尝试处理的图像的分辨率大于阵列可以具有的分辨率(95168x154832)。所以基本上你将无法读取图像,因为 ImageIO.createImageInputStream()尝试将整个图像加载到数组AFAIK中。


The resolution of the image you are trying to process is larger than an array can have (95168x154832). So basically you will not be able to read the image, since ImageIO.createImageInputStream() tries to load the whole image into an array AFAIK.

可以做的是使用名为 ImgLib2 的库。 此处您可以找到一些示例。 ImgLib2 使用多维数组来读取(大)图像数据,因此它大于 ImageIO 可以处理。

What you can do is use a library called ImgLib2. Here you can find some examples. ImgLib2 uses multidimensional arrays to read the (big) image data and so it's larger than ImageIO can handle.

这篇关于从大的jp2图像读取像素,而不将整个图像加载到内存中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆