缓冲图像像素操作
我有这样的代码:
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 或当使用数组时或当我在传递 getRGB 之前分配数组时抛出 ArrayOutOfBoundsException 。我检查调试器,图像具有大小并已分配。
更新: 获取RGB
/**
* 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, 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;
}
I have this code:
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);
}
It throws NPE or when array is used or ArrayOutOfBoundsException when I allocate array before passing it getRGB. I check in debugger and image has the size and is allocated.
UPDATE:
The 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, 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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有两个问题:
数组的宽度不是图像的宽度,而是“扫描大小”(某些图像大小会用额外的像素填充)
如果您使用
null
数组调用getRGB()
,该方法将创建一个数组,但它不会改变rgb
参考 - Java 不支持“输出参数”。为了使这项工作正常进行,请使用
There are two problems:
The width of the array is not the width of the image but the "scan size" (some image sizes get padded with extra pixels)
If you call
getRGB()
with anull
array, the method will create an array but it won't change thergb
reference - Java doesn't support "out parameters".To make this work, use
您的代码将引发
NullPointerException
,因为您从未将非空引用分配给rgb
变量。因此,对它的引用(例如rgb[index]
)将生成异常。如果您希望将空数组传递给 getRGB,则需要确保分配该方法返回的结果数组;例如,如果您要取消注释注释掉的代码,则存在一个错误,即您将数组分配为
imageWidth * imageWidth
而不是imageWidth * imageHeight
,这就是您的原因看到ArrayIndexOutOfBoundsException
。Your code will throw a
NullPointerException
because you are never assigning a non-null reference to thergb
variable. Hence, references to it (e.g.rgb[index]
) will generate the exception. If you wish to pass in a null array to getRGB you need to ensure you assign the result array returned by the method; e.g.If you were to uncomment the code commented out there is a bug in that you are allocating the array as
imageWidth * imageWidth
instead ofimageWidth * imageHeight
, which is why you're seeing anArrayIndexOutOfBoundsException
.