2013-04-18 89 views
1

我正在開發圖像處理,並且我想使用seekbar應用模糊效果。 我使用下面的代碼模糊的位圖和它的作品,但現在我想要去模糊的位圖,我無法實現...... PLZ幫我解決這個問題如何在seekbar變化上使位圖變模糊和刪除

private Bitmap blurfast(Bitmap bmp, int radius) { 
     int w = bmp.getWidth(); 
     int h = bmp.getHeight(); 
     int[] pix = new int[w * h]; 
     bmp.getPixels(pix, 0, w, 0, 0, w, h); 

     for(int r = radius; r >= 1; r /= 2) 
     { 
      for(int i = r; i < h - r; i++) 
      { 
       for(int j = r; j < w - r; j++) 
       { 
        int tl = pix[(i - r) * w + j - r]; 
        int tr = pix[(i - r) * w + j + r]; 
        int tc = pix[(i - r) * w + j]; 
        int bl = pix[(i + r) * w + j - r]; 
        int br = pix[(i + r) * w + j + r]; 
        int bc = pix[(i + r) * w + j]; 
        int cl = pix[i * w + j - r]; 
        int cr = pix[i * w + j + r]; 

      pix[(i * w) + j] = 0xFF000000 | 
      (((tl & 0xFF) + (tr & 0xFF) + (tc & 0xFF) + (bl & 0xFF) + 
(br & 0xFF) + (bc & 0xFF) + (cl & 0xFF) + (cr & 0xFF)) >> 3) & 0xFF | 
      (((tl & 0xFF00) + (tr & 0xFF00) + (tc & 0xFF00) + (bl & 0xFF00) 
+ (br & 0xFF00) + (bc & 0xFF00) + (cl & 0xFF00) + (cr & 0xFF00)) >> 3) & 0xFF00 | 
      (((tl & 0xFF0000) + (tr & 0xFF0000) + (tc & 0xFF0000) + 
(bl & 0xFF0000) + (br & 0xFF0000) + (bc & 0xFF0000) + (cl & 0xFF0000) + 
(cr & 0xFF0000)) >> 3) & 0xFF0000; 
       } 
      } 
     } 
     bmp.setPixels(pix, 0, w, 0, 0, w, h); 
     return bmp; 
    } 
+2

一旦圖像模糊,就不能「模糊」圖像。您可以實現的唯一方法是保留原件的副本並在必要時進行恢復。 –

+0

感謝您的回放,但我需要這樣做,是處理模糊效果的任何單一解決方案..? –

+0

我不認爲這是可能的,因爲模糊實際上改變了像素值,然後你會丟失圖像的一些數據,所以即使你顛倒了算法,你也不會回到原始圖像,所以你必須保存原始圖像之前修改它。 –

回答

1

你不能「去模糊化」的形象一旦模糊。您可以實現的唯一方法是保留原件的副本並在必要時進行恢復。 只有處理模糊的方法是始終模糊從原始圖像。您將需要重新組織你的代碼以下列方式:

private Bitmap origBitmap; 
... 

Bitmap bmp = //get your starting bitmap here; 
origBitmap = Bitmap.createBitmap(bmp); 

... 

seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
     Bitmap blurred = blurfast(origBitmap, progress); 
     //now draw your blurred bitmap into wherever you need it to be 
    } 

    public void onStartTrackingTouch(SeekBar seekBar) {} 
    public void onStopTrackingTouch(SeekBar seekBar) {} 
}); 
... 

private Bitmap blurfast(Bitmap bmp, int radius) { 
     int w = bmp.getWidth(); 
     int h = bmp.getHeight(); 
     int[] pix = new int[w * h]; 
     bmp.getPixels(pix, 0, w, 0, 0, w, h); 

     for(int r = radius; r >= 1; r /= 2) 
     { 
      for(int i = r; i < h - r; i++) 
      { 
       for(int j = r; j < w - r; j++) 
       { 
        int tl = pix[(i - r) * w + j - r]; 
        int tr = pix[(i - r) * w + j + r]; 
        int tc = pix[(i - r) * w + j]; 
        int bl = pix[(i + r) * w + j - r]; 
        int br = pix[(i + r) * w + j + r]; 
        int bc = pix[(i + r) * w + j]; 
        int cl = pix[i * w + j - r]; 
        int cr = pix[i * w + j + r]; 

      pix[(i * w) + j] = 0xFF000000 | 
      (((tl & 0xFF) + (tr & 0xFF) + (tc & 0xFF) + (bl & 0xFF) + 
(br & 0xFF) + (bc & 0xFF) + (cl & 0xFF) + (cr & 0xFF)) >> 3) & 0xFF | 
      (((tl & 0xFF00) + (tr & 0xFF00) + (tc & 0xFF00) + (bl & 0xFF00) 
+ (br & 0xFF00) + (bc & 0xFF00) + (cl & 0xFF00) + (cr & 0xFF00)) >> 3) & 0xFF00 | 
      (((tl & 0xFF0000) + (tr & 0xFF0000) + (tc & 0xFF0000) + 
(bl & 0xFF0000) + (br & 0xFF0000) + (bc & 0xFF0000) + (cl & 0xFF0000) + 
(cr & 0xFF0000)) >> 3) & 0xFF0000; 
       } 
      } 
     } 
     Bitmap blurred = Bitmap.createBitmap(w, h, bmp.getConfig); 
     blurred.setPixels(pix, 0, w, 0, 0, w, h); 
     return blurred; 
    } 

有幾件事情需要注意:

  1. 在您聲明Bitmap類型的私有成員變量開始,將舉行您原始位圖,在任何模糊已被應用之前。

  2. 每當您的seekbar移動時,您將模糊應用到原始位圖,而不是您的位圖的當前狀態。

  3. blurfast方法中,您需要創建一個具有模糊像素的新位圖,而不是更新傳入它的位圖(注意我的代碼中的最後三行)。

  4. 最後,請記住,如果您的位圖很大,可能會導致內存不足,請密切關注內存使用情況。

我沒有測試此代碼,所以不能保證,這正是你需要的,但這應該讓你開始。

+0

所以你做一個巨大的內存使用(位圖)的參考: –

+0

我不會說「巨大」。您不知道原始位圖的位數。它可能只有320x240像素,在這種情況下,內存很小。保留副本是實現OP所需內容的唯一方法。 –

+0

是的...你總是從原始位圖改變的想法,真的幫助我解決這個問題,謝謝兄弟,這是我在尋找什麼。 –