我正在尝试使用Bitmaps在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;
}
}
}
}
答案 0 :(得分:3)
你没有显示堆栈跟踪(编辑:现在你做了,谢谢),这将指示哪一行抛出异常。
然而,乍一看,您的问题似乎就在这里:
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滤镜直接应用于图像的边缘,因此滤镜会超出图像边界。考虑你的第一次迭代:
然后您尝试访问pixels[x+filterX+width*(y+filterY)]
:
所以你可以看到,访问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++) {
这适用于所有奇数尺寸的过滤器。