2013-08-06 289 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循環?最後我對此做了記錄。我會盡力改進。給我一點時間。 –