Java 调用Raster.setRect()时发生ArrayIndexOutOfBoundsException

Java 调用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

我写了一个读取图像的方法。我循环浏览图像文件列表并读取它们。在一些迭代之后,当调用Raster.setRect(光栅光栅)方法时,会出现ArrayIndexOutOfBoundsException。图像的尺寸和边界很好-参见stacktrace

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) {}
    }
}