Java 缓冲图像像素处理

Java 缓冲图像像素处理,java,bufferedimage,pixel-manipulation,Java,Bufferedimage,Pixel Manipulation,我有以下代码: public Image toNegative() { int imageWidth = originalImage.getWidth(); int imageHeight = originalImage.getHeight(); int [] rgb = null; // new int[imageWidth * imageWidth]; originalImage.getRGB(0, 0, imageWidth, imageHeight, r

我有以下代码:

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);
}
* * * *可能会抛出
BoundsException数组
*如果区域不在边界内。
*但是,不能保证显式边界检查。
*
*@param startX起始X坐标
*@param startY起始Y坐标
*@param w区域宽度
*@param h区域高度
*@param rgbArray如果不是
null
,则rgb像素为 *写在这里 *@param offset偏移到
rgbArray
*@param scansize用于
rgbArray
*@返回RGB像素数组。 *@see#setRGB(int,int,int) *@see#setRGB(int,int,int,int,int,int[],int,int) */ 公共int[]getRGB(int-startX、int-startY、int-w、int-h、, int[]rgbArray,int offset,int scansize){ int yoff=偏移量; int off; 对象数据; int nbands=graster.getNumBands(); int dataType=graster.getDataBuffer().getDataType(); 交换机(数据类型){ case DataBuffer.TYPE_字节: 数据=新字节[nbands]; 打破 case DataBuffer.TYPE_USHORT: 数据=新的短[nbands]; 打破 case DataBuffer.TYPE_INT: 数据=新的整数[n位数]; 打破 case DataBuffer.TYPE_FLOAT: 数据=新浮点数[n位数]; 打破 case DataBuffer.TYPE_DOUBLE: 数据=新的双[n个]; 打破 违约: 抛出新的IllegalArgumentException(“未知数据缓冲区类型:”+ 数据类型); } if(rgbArray==null){ rgbArray=新整数[偏移量+h*扫描大小]; } 对于(int y=startY;y
您的代码将抛出一个
NullPointerException
,因为您从未为
rgb
变量分配非空引用。因此,对它的引用(例如,
rgb[index]
)将生成异常。如果希望将null数组传递给getRGB,则需要确保分配该方法返回的结果数组;e、 g

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

如果要取消注释注释注释掉的代码,则存在一个错误,即您将数组分配为
imageWidth*imageWidth
,而不是
imageWidth*imageHeight
,这就是为什么您会看到
ArrayIndexOutOfBoundsException
存在两个问题:

  • 数组的宽度不是图像的宽度,而是“扫描大小”(一些图像大小会被额外的像素填充)

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

  • 要使此工作正常,请使用


    不。在getRGB内部是if(rgbArray==null){rgbArray=new int[offset+h*scansize];}至少NetBeans显示的是etrgb可以执行空检查(我没有看过),但您仍然试图在代码的更深处索引到空数组,这就是为什么您会看到NullPointerException。如果你想传入一个空数组,你需要将getRGB的结果分配给你的rgb引用,以避免NPE(参见我的编辑)。啊,它被抛出到了其他地方
    int[] rgb = originalImage.getRGB(0, 0, imageWidth, imageHeight, rgb, 0,imageWidth);
    
    rgb = originalImage.getRGB(0, 0, imageWidth, imageHeight, null, 0,imageWidth);