2011-10-12 66 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);