2013-08-06 290 views
0

我想在Android中使用位图实现平均/平均3x3过滤器。ArrayIndexOutOfBoundsException从像素数组中计算平均值/平均值

每当我尝试应用此过滤器时,应用程序都会关闭。当我尝试在图像上应用此过滤器时出现错误,我得到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

请发布堆栈跟踪并指出导致异常的行。 –

+0

@JasonC如何获取堆栈跟踪数据? – User1204501

+0

只需发布你的错误 – Loki

回答

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的过滤器,图像的边缘,所以滤镜不在图像边界之内。考虑你非常第一次迭代:

  • 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 + -width

因此可以看出,访问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++) { 

,会为所有的奇数大小的过滤器工作。

+0

我发布了错误 – User1204501

+0

谢谢。这似乎证实了我的怀疑。 –

+0

@ User1204501你的意思是filterX/filterY循环?最后我对此做了记录。我会尽力改进。给我一点时间。 –