Java 调用Raster.setRect()时发生ArrayIndexOutOfBoundsException
我写了一个读取图像的方法。我循环浏览图像文件列表并读取它们。在一些迭代之后,当调用Raster.setRect(光栅光栅)方法时,会出现ArrayIndexOutOfBoundsException。图像的尺寸和边界很好-参见stacktraceJava 调用Raster.setRect()时发生ArrayIndexOutOfBoundsException,java,image,javax.imageio,Java,Image,Javax.imageio,我写了一个读取图像的方法。我循环浏览图像文件列表并读取它们。在一些迭代之后,当调用Raster.setRect(光栅光栅)方法时,会出现ArrayIndexOutOfBoundsException。图像的尺寸和边界很好-参见stacktrace public static BufferedImage readImage(File imageFile) { // Find a suitable ImageReader Iterator<ImageReader> rea
public static BufferedImage readImage(File imageFile) {
// Find a suitable ImageReader
Iterator<ImageReader> readers = ImageIO.getImageReadersBySuffix("jpg");
ImageReader reader = null;
while (readers.hasNext()) {
reader = (ImageReader) readers.next();
if (reader.canReadRaster()) {
break;
}
}
// Stream the image file (the original CMYK image)
ImageInputStream input = null;
try {
input = ImageIO.createImageInputStream(imageFile);
} catch (IOException e) {
logger.error("Error creating InputStream on File {}", imageFile
.getName());
e.printStackTrace();
}
reader.setInput(input);
// Read the image raster
Raster raster = null;
try {
raster = reader.readRaster(0, null);
} catch (IOException e) {
logger
.error("Error reading Raster of file {}", imageFile
.getName());
e.printStackTrace();
}
// Create a new RGB image
BufferedImage bi = new BufferedImage(raster.getWidth(), raster
.getHeight(), BufferedImage.TYPE_INT_RGB);
// Fill the new image with the old raster
logger.debug("Height {} and width {} of original raster", raster
.getHeight(), raster.getWidth());
logger.debug("Height {} and width {} of new raster", bi.getRaster()
.getHeight(), bi.getRaster().getWidth());
logger.debug("NumBands original raster {}", bi.getRaster().getBounds());
logger.debug("NumBands new raster {}", bi.getRaster().getBounds());
bi.getRaster().setRect(raster);
// Close and flush the reader
try {
input.close();
} catch (IOException e) {
logger.error("Error closing the reader for file {}", imageFile
.getName());
e.printStackTrace();
}
return bi;
}
所有图像都具有相同的尺寸371x310
这里是我打印的调试信息:
13:53:17.065 [main] DEBUG .. .ImageUtils - Height 371 and width 310 of original raster
13:53:17.065 [main] DEBUG .. .ImageUtils - Height 371 and width 310 of new raster
13:53:17.065 [main] DEBUG .. .ImageUtils - NumBands original raster java.awt.Rectangle[x=0,y=0,width=310,height=371]
13:53:17.065 [main] DEBUG .. .ImageUtils - NumBands new raster java.awt.Rectangle[x=0,y=0,width=310,height=371]
文档中说:ArrayIndexOutOfBoundsException-如果坐标不在边界内,或者fArray太小,无法容纳输入
对我来说,尺寸/边界似乎很好,可能是法拉利的问题?我想问题不在于图像尺寸,而在于光栅中的波段数。您可以创建BuffereImage.TYPE\u INT\u RGB。 可能失败的图像是带有alpha通道的PNG,在这种情况下,光栅有一个额外的波段 我想知道你为什么要以这种复杂的方式进行加载,为什么不直接使用ImageIo.read(InputStream)?这将为您提供一个BuffereImage,无需自己进行转换 编辑: 尝试此方法读取并转换为RGB:
InputStream input = null;
try {
input = new FileInputStream(...); // whatever your source is
BufferedImage rawImage = ImageIO.read(input);
if (rawImage == null)
return null;
BufferedImage rgbImage = new BufferedImage(rawImage.getWidth(null), rawImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics g = rgbImage.createGraphics();
// if rawImage contains alpha, consider filling the rgbImage with a default BG color here
g.drawImage(rawImage, 0, 0, null);
g.dispose();
rawImage.flush();
return rgbImage;
} catch (Exception e) {
// handle error
return null;
} finally {
// close input if open
if (input != null) {
try {
input.close();
} catch (IOException e) {}
}
}
只是把代码拼凑在一起,可能有打字错误。这样,无论源文件是什么,您都可以获得RGB图像,而无需考虑源图像的属性。您走的路是对的:我检查了两幅图像的波段。14:59:49.334[主]调试。utils.ImageUtils-Numands原始光栅1 14:59:49.334[主]调试。fraud.utils.ImageUtils-NumBands new raster 3我使用这种阅读方式,因为我有CMYK格式的图像。尝试编辑代码以修复此问题感谢您的代码,但它仍然无法与CMYK JPGs一起工作。因为我在项目中使用了JavaCV/OpenCV,所以我决定使用它们的读取方法来读取图像,并将其转换为缓冲图像。性能可以接受。似乎CMYK不受ImageIO现成支持。我记得当有人将CMYK jpg上传到CMS时,PHP也遇到了类似的问题,令人惊讶的是,当CMS缩放图像时,图像被破坏了。然而,似乎有人已经解决了ImageIO的问题:如果您仍然有问题,该链接可能会有所帮助。
InputStream input = null;
try {
input = new FileInputStream(...); // whatever your source is
BufferedImage rawImage = ImageIO.read(input);
if (rawImage == null)
return null;
BufferedImage rgbImage = new BufferedImage(rawImage.getWidth(null), rawImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics g = rgbImage.createGraphics();
// if rawImage contains alpha, consider filling the rgbImage with a default BG color here
g.drawImage(rawImage, 0, 0, null);
g.dispose();
rawImage.flush();
return rgbImage;
} catch (Exception e) {
// handle error
return null;
} finally {
// close input if open
if (input != null) {
try {
input.close();
} catch (IOException e) {}
}
}