如何在搜索栏更改时模糊和去模糊位图

时间:2013-04-18 08:16:20

标签: android canvas bitmap

我正在开发图像处理,我想使用搜索栏应用模糊效果。 我使用下面的代码模糊位图,它的工作原理,但现在我想deblur我无法实现的位图... PLZ帮助我解决这个问题

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;
    }

1 个答案:

答案 0 :(得分:1)

你不能去除'#34;图像一旦模糊。您可以实现它的唯一方法是保留原件的副本并在必要时恢复它。处理模糊的唯一方法是始终从原始图像模糊。您需要以下列方式重新组织代码:

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. 每当搜索栏移动时,您都会将模糊应用于原始位图,而不是位图的当前状态。

  3. blurfast方法中,您需要创建一个带有模糊像素的新位图,而不是更新传入其中的位图(注意我代码中的最后三行)。

    < / LI>
  4. 最后,请记住,如果您的位图很大,可能会耗尽内存,因此请密切关注内存使用情况。

  5. 我还没有对此代码进行测试,因此无法保证这正是您所需要的,但这应该可以让您开始使用。