坐标超出范围:bufferedimage

时间:2014-09-01 17:01:48

标签: java rgb bufferedimage

我制作了一个程序来分隔图像的红色和绿色组件,但下面的代码会出错:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
at sun.awt.image.ByteInterleavedRaster.getDataElements(ByteInterleavedRaster.java:318)
at java.awt.image.BufferedImage.getRGB(BufferedImage.java:888)
at rgb.Rgb.main(Rgb.java:46):

以下是源代码:

public static void main(String[] args) {
    String type = "jpg";
    BufferedImage img = null;
    try {
        img = ImageIO.read(new File("d:\\a.jpg"));
        System.out.println(img.getWidth() + "     " + img.getHeight());

    } catch (IOException ex) {
        Logger.getLogger(Rgb.class.getName()).log(Level.SEVERE, null, ex);

    }

    BufferedImage rp, gp, bp;

    rp = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
    bp = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
    gp = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);

    for (int i = 1; i <= img.getHeight(); i++) {
        for (int j = 1; j <= img.getWidth(); j++) {

            int pixel = img.getRGB(i, j);
            int alpha = pixel & 0xff000000;
            int red = (pixel >> 16) & 0xff;
            int green = (pixel >> 8) & 0xff;
            int blue = (pixel) & 0xff;
            rp.setRGB(i, j, alpha | (red << 16));
            gp.setRGB(i, j, alpha | (green << 8));
            bp.setRGB(i, j, alpha | blue);

        }

    }

    try {
        ImageIO.write(rp, type, new File("d:\\red.jpg"));
        ImageIO.write(gp, type, new File("d:\\green.jpg"));
        ImageIO.write(bp, type, new File("d:\\blue.jpg"));
    } catch (IOException ex) {
        Logger.getLogger(Rgb.class.getName()).log(Level.SEVERE, null, ex);
    }

2 个答案:

答案 0 :(得分:3)

方法是getRGB(x,y),意味着你的外环应该是宽度,内环是高度。改为

for (int i = 0; i < img.getWidth(); i++) {
        for (int j = 0; j < img.getHeight(); j++) {

<强>原因
你正试图得到一个不存在的坐标。这是因为

  1. 你的循环应该从0开始并结束到getWidth() - 1 / getHeight() - 1作为最后一个坐标是(WIDTH-1,HEIGHT-1)
  2. 外部循环获得y值而内部循环获得x值,因此您尝试获取(y,x)值,而它应该是(x,y)值。如果它是正方形图片,这不会导致任何问题,但如果它是矩形的,则会导致例外情况发生异常。
  3. 因此,按照我在代码中的建议进行更改,它应该可以正常工作。

答案 1 :(得分:1)

你得到一个ArrayIndexOutOfBoundsException,因为你的for循环是一个。像素索引从0开始(不是1)并运行到getWidth() - 1和getHeight() - 1。

第二个问题是你在调用getRGB()时交换参数。 getRGB的签名是getRGB(int x,int y),但是你调用的是getRGB(y,x)。

您正在循环遍历图像(外部循环遍历行,内部循环遍历列)。不要像其他答案所建议的那样交换循环,但要交换提供给getRGB的参数的顺序。

以下是更正后的代码,i和j重命名为row和col以帮助澄清:

for (int row = 0; row < img.getHeight(); row++) 
{
    for (int col = 0; col < img.getWidth(); col++) 
    {
        int pixel = img.getRGB(col, row);    // getRGB(x,y)
        int alpha = pixel & 0xff000000;
        int red = (pixel >> 16) & 0xff;
        int green = (pixel >> 8) & 0xff;
        int blue = (pixel) & 0xff;
        rp.setRGB(col, row, alpha | (red << 16));
        gp.setRGB(col, row, alpha | (green << 8));
        bp.setRGB(col, row, alpha | blue);
    }
}