我试图从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<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)
请帮忙阅读这张大图中的部分内容?
答案 0 :(得分:0)
有不同的方法可以将部分图像加载到内存中,然后再处理它。您可以尝试以下方法来读取片段:
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));
这在this主题中标记为正确答案。
如果需要,可以使用此技术最终将整个图像读入内存。
修改强>
您尝试处理的图像的分辨率大于阵列可以具有的分辨率(95168x154832)。所以基本上你将无法读取图像,因为ImageIO.createImageInputStream()
试图将整个图像加载到阵列AFAIK中。
可以做的是使用名为ImgLib2
的库。 Here你可以找到一些例子。 ImgLib2
使用多维数组来读取(大)图像数据,因此它大于ImageIO
可以处理的数据。