从大的jp2图像读取像素,而不将整个图像加载到内存中

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

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 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.(SampleModel.java:130) at java.awt.image.ComponentSampleModel.(ComponentSampleModel.java:146) at java.awt.image.PixelInterleavedSampleModel.(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.(J2KRenderedImageCodecLib.java:261) at com.sun.media.imageioimpl.plugins.jpeg2000.J2KImageReaderCodecLib.read(J2KImageReaderCodecLib.java:364) at testJai2.test3.main(test3.java:21) 

请帮忙从这张大图中读取零件?

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

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

这在此主题中标记为正确答案。

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

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

可以做的是使用一个名为ImgLib2的库。 在这里你可以找到一些例子。 ImgLib2使用多维数组来读取(大)图像数据,因此它比ImageIO可以处理的更大。