2011-10-12 135 views
2

我有这样的代码:缓冲的图像像素处理

public Image toNegative() 
{ 
    int imageWidth = originalImage.getWidth(); 
    int imageHeight = originalImage.getHeight(); 
    int [] rgb = null; // new int[imageWidth * imageWidth]; 
    originalImage.getRGB(0, 0, imageWidth, imageHeight, rgb, 0,imageWidth); 

    for (int y = 0; y < imageHeight; y++) 
    { 
     for (int x = 0; x < imageWidth; x++) 
     { 
      int index = y * imageWidth + x; 
      int R = (rgb[index] >> 16) & 0xff;  //bitwise shifting 
      int G = (rgb[index] >> 8) & 0xff; 
      int B = rgb[index] & 0xff; 

      R = 255 - R; 
      G = 255 - R; 
      B = 255 - R; 

      rgb[index] = 0xff000000 | (R << 16) | (G << 8) | B;         
     } 
    } 


    return getImageFromArray(rgb, imageWidth, imageHeight); 
} 

它将引发NPE或使用或ArrayOutOfBoundsException阵列时,当我传递之前的getRGB分配阵列。我检查调试器和图像的大小和分配。

UPDATE: 的的getRGB

/** 
* Returns an array of integer pixels in the default RGB color model 
* (TYPE_INT_ARGB) and default sRGB color space, 
* from a portion of the image data. Color conversion takes 
* place if the default model does not match the image 
* <code>ColorModel</code>. There are only 8-bits of precision for 
* each color component in the returned data when 
* using this method. With a specified coordinate (x,&nbsp;y) in the 
* image, the ARGB pixel can be accessed in this way: 
* </p> 
* 
* <pre> 
* pixel = rgbArray[offset + (y-startY)*scansize + (x-startX)]; </pre> 
* 
* <p> 
* 
* An <code>ArrayOutOfBoundsException</code> may be thrown 
* if the region is not in bounds. 
* However, explicit bounds checking is not guaranteed. 
* 
* @param startX  the starting X coordinate 
* @param startY  the starting Y coordinate 
* @param w   width of region 
* @param h   height of region 
* @param rgbArray if not <code>null</code>, the rgb pixels are 
*   written here 
* @param offset  offset into the <code>rgbArray</code> 
* @param scansize scanline stride for the <code>rgbArray</code> 
* @return   array of RGB pixels. 
* @see #setRGB(int, int, int) 
* @see #setRGB(int, int, int, int, int[], int, int) 
*/ 
public int[] getRGB(int startX, int startY, int w, int h, 
        int[] rgbArray, int offset, int scansize) { 
    int yoff = offset; 
    int off; 
    Object data; 
    int nbands = raster.getNumBands(); 
    int dataType = raster.getDataBuffer().getDataType(); 
    switch (dataType) { 
    case DataBuffer.TYPE_BYTE: 
     data = new byte[nbands]; 
     break; 
    case DataBuffer.TYPE_USHORT: 
     data = new short[nbands]; 
     break; 
    case DataBuffer.TYPE_INT: 
     data = new int[nbands]; 
     break; 
    case DataBuffer.TYPE_FLOAT: 
     data = new float[nbands]; 
     break; 
    case DataBuffer.TYPE_DOUBLE: 
     data = new double[nbands]; 
     break; 
    default: 
     throw new IllegalArgumentException("Unknown data buffer type: "+ 
              dataType); 
    } 

    if (rgbArray == null) { 
     rgbArray = new int[offset+h*scansize]; 
    } 

    for (int y = startY; y < startY+h; y++, yoff+=scansize) { 
     off = yoff; 
     for (int x = startX; x < startX+w; x++) { 
      rgbArray[off++] = colorModel.getRGB(raster.getDataElements(x, 
                    y, 
                    data)); 
     } 
    } 

    return rgbArray; 
} 

回答

1

您的代码会抛出一个NullPointerException因为你从来没有指派一个非空参照rgb变量。因此,对其的引用(例如rgb[index])将产生异常。如果你想传递一个null数组到getRGB,你需要确保你分配了方法返回的结果数组;例如

int[] rgb = originalImage.getRGB(0, 0, imageWidth, imageHeight, rgb, 0,imageWidth); 

如果要取消注释代码注释掉存在这样的错误你是分配数组作为imageWidth * imageWidth,而不是imageWidth * imageHeight,这就是为什么你看到的ArrayIndexOutOfBoundsException

+0

都能跟得上。里面的getRGB是if(rgbArray == null){rgbArray = new int [offset + h * scansize]; }至少有哪些NetBeans显示 –

+2

getRGB可能会执行空检查(我没有看过),但是您仍尝试在代码中进一步索引到null数组中,这就是为什么您会看到NullPointerException。如果你想传入一个空数组,你需要将getRGB的结果赋给你的rgb引用,以避免NPE(参见我的编辑)。 – Adamski

+0

啊它被扔到别的地方了 –

4

有两个问题:

  1. 数组的宽度不是图像的宽度,但“扫描尺寸”(一些图像尺寸得到额外的像素填充)

  2. 如果您使用null数组调用getRGB(),该方法将创建一个数组,但它不会更改rgb引用 - Java不支持“out参数”。

为了使这项工作,使用

rgb = originalImage.getRGB(0, 0, imageWidth, imageHeight, null, 0,imageWidth);