缓冲图像像素操作

我有这个代码:

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

当我在传递getRGB之前分配数组时,它会抛出NPE或使用数组时抛出ArrayOutOfBoundsException。 我签入调试器并且图像具有大小并被分配。

更新: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 * ColorModel. There are only 8-bits of precision for * each color component in the returned data when * using this method. With a specified coordinate (x, y) in the * image, the ARGB pixel can be accessed in this way: * 

* *
 * pixel = rgbArray[offset + (y-startY)*scansize + (x-startX)]; 

* *

* * An ArrayOutOfBoundsException 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 null, the rgb pixels are * written here * @param offset offset into the rgbArray * @param scansize scanline stride for the rgbArray * @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; }

您的代码将抛出NullPointerException因为您永远不会为rgb变量分配非空引用。 因此,对它的引用(例如rgb[index] )将生成exception。 如果您希望将null数组传入getRGB,则需要确保分配方法返回的结果数组; 例如

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

如果您要取消注释注释掉的代码,则会出现一个错误,即您将数组分配为imageWidth * imageWidth而不是imageWidth * imageHeight ,这就是您看到ArrayIndexOutOfBoundsException

有两个问题:

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

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

要使这项工作,请使用

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