我正在尝试使用位图在 Android 中实现平均/平均 3x3 过滤器。
每次我尝试应用此过滤器时,应用程序都会不断关闭。当我尝试在图像上应用此过滤器时,出现 ArrayIndexOutOfBoundsException 错误。
我的代码如下:
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int index = 0;
for (int filterX = -filterWidth / 2; filterX < filterWidth / 2; filterX++) {
for (int filterY = -filterHeight / 2; filterY < filterHeight / 2; filterY++) {
A = (pixels[x+filterX+width*(y+filterY)])>>24 & 0xFF;
R = (pixels[x+filterX+width*(y+filterY)] >> 16) & 0xFF;
G = (pixels[x+filterX+width*(y+filterY)] >> 8) & 0xFF;
B = pixels[x+filterX+width*(y+filterY)] & 0xFF;
}
}
}
}
最佳答案
您没有显示堆栈跟踪(编辑:现在您可以了,谢谢),这将指示哪一行抛出异常。
但是乍一看,您的问题似乎在这里:
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int index = 0;
for (int filterX = -filterWidth / 2; filterX < filterWidth / 2; filterX++) {
for (int filterY = -filterHeight / 2; filterY < filterHeight / 2; filterY++) {
A = (pixels[x+filterX+width*(y+filterY)])>>24 & 0xFF;
R = (pixels[x+filterX+width*(y+filterY)] >> 16) & 0xFF;
G = (pixels[x+filterX+width*(y+filterY)] >> 8) & 0xFF;
B = pixels[x+filterX+width*(y+filterY)] & 0xFF;
...
}
}
}
}
您超出了像素数组的范围,因为您尝试将 3x3 滤镜直接应用于图像边缘,因此滤镜超出了图像范围。考虑您的第一次迭代:
- x = 0
- y = 0
- filterX = -filterWidth/2 = -3/2 = -1
- filterY = -filterHeight/2 = -3/2 = -1
然后您尝试访问 pixels[x+filterX+width*(y+filterY)]
:
- 0 + -1 + 宽度 * (0 + -1)
- = -1 + -宽度
所以你可以看到,访问 pixels[-1 + -width]
显然是越界了。如果你的filterX/filterY循环是正确的,同样的情况也会发生在上限(参见这个答案底部的注释——目前你的大小为3,filterX和filterY停止在0,而不是1)。
您要么不需要在距边缘的filterWidth/2(或filterHeight/2垂直)像素内应用过滤器,要么需要在读取图像像素时进行一些边界检查并将边缘之外的区域视为0 .
一种可能的优化是在图像周围创建一个filterWidth/2(或filterHeight/2垂直)黑色边框,并且不处理边缘附近的那些像素。那么你就不需要分支来进行边界检查。
顺便说一句,对于奇数尺寸的过滤器,您需要执行 <= filterWidth / 2
(高度相同)在循环中:
for (int filterX = -filterWidth / 2; filterX <= filterWidth / 2; filterX++) {
for (int filterY = -filterHeight / 2; filterY <= filterHeight / 2; filterY++) {
这适用于所有奇数尺寸的过滤器。
关于java - 从像素数组计算平均值时出现 ArrayIndexOutOfBoundsException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18074678/