在将像素数组转换为Java中的Image时,Array Index of Bound

时间:2016-08-04 17:48:19

标签: java arrays swing

我在stackoverflow上找到了这个方法:

    public static Image getImageFromArray(int[] pixels, int width, int height) {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        WritableRaster raster = (WritableRaster) image.getData();
        raster.setPixels(0,0,width,height,pixels);
        return image;
    }

像这样使用它:

        image = getImageFromArray(dstpixels,img.getWidth(this),img.getHeight(this));

为了调试我打印出dstpixels的宽度,高度和长度,结果如下: 700 389 272300

我仍然收到此错误  Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 272300

在这一行上

            raster.setPixels(0,0,width,height,pixels);

我错过了什么?

3 个答案:

答案 0 :(得分:2)

看起来Raster不会将pixels视为每个元素代表单个像素的数组。它将其视为数组,其中每个元素包含有关像素的单个信息 因此,如果它是ARGB类型的图像,它看起来像pixel数组将包含前四个元素中第一个像素的信息(在索引[0,1,2,3]

  • R将存储在[0]
  • 位置 位于G
  • [1] 位于B
  • [2] 位于A
  • [3](alpha)。

有关第二个像素的信息将放置在[4,5,6,7]个索引,第三个[8,9,10,11],依此类推。

因此,通过为ARGB类型的图像分配4倍大的int[] pixel数组(对于RGB大3倍),可以解决问题的主要问题。

代码中的另一个问题是image.getData()

  

将图像作为一个大图块返回。返回的光栅是图像的 副本 如果图像发生更改,则不会更新数据。

(强调我的)

因此操纵raster的数据不会影响image。要使用栅格数据更新图片,您需要在image.setData(raster);方法中添加getImageFromArray,例如

public static Image getImageFromArray(int[] pixels, int w, int h) {
    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    WritableRaster raster = (WritableRaster) image.getData();
    raster.setPixels(0,0,w,h,pixels);
    image.setData(raster); //<-- add this line
    return image;
}

或者根本不使用image.getData(),而是操纵图像使用的栅格。您可以通过image.getRaster()

获取

演示:

enter image description here

public static void main(String[] args) {
    int width = 200, height = 300;
    //array needs to be 4 times larger than amount of pixels
    int[] pixels = new int[4*width*height];
    for (int i = 0; i < pixels.length; i++) {
        //if (i%4==0){pixels[i]=255;}//R default 0
        //if (i%4==1){pixels[i]=255;}//G default 0
        if (i%4==2){pixels[i]=255;}//B default 0 
        //Alpha
        if (i%4==3){        
            pixels[i]=(int)(255*(i/4%width)/(double)width);
        }
    }
    Image image = getImageFromArray(pixels, width, height);
    showImage(image);
}
public static void showImage(Image img){
    JFrame frame = new JFrame();
    frame.setLayout(new FlowLayout());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JLabel lab = new JLabel(new ImageIcon(img));
    frame.add(lab);
    frame.pack();
    frame.setVisible(true);
}
public static Image getImageFromArray(int[] pixels, int w, int h) {
    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    WritableRaster raster = image.getRaster();
    raster.setPixels(0,0,w,h,pixels);
    return image;
}

答案 1 :(得分:0)

  

为了调试我打印出dstpixels的宽度,高度和长度,结果如下:700 389 272300

并且

  

我仍然收到此错误线程中的异常&#34; AWT-EventQueue-0&#34; java.lang.ArrayIndexOutOfBoundsException: 272300

如果数组大小为N,则第一个元素的索引为0,最后一个元素的索引为N-1(在您的情况下为0和272299)

答案 2 :(得分:0)

似乎你的一个参数应该是272300-1!

异常告诉你某些东西访问索引272300,如果它是维度的SIZE则不会起作用;然后最后一个索引如272300-1所述。

换句话说:总是仔细阅读异常消息,它会告诉您所有需要知道的事情!