1

我正在开发图像处理,我想使用 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;
    }
4

1 回答 1

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. 在开始时,您要声明一个私有成员变量 type Bitmap,它将在应用任何模糊之前保存您的原始位图。

  2. 每当您的搜索栏移动时,您将模糊应用于原始位图,而不是位图的当前状态。

  3. 在该blurfast方法中,您需要使用模糊像素创建一个新位图,而不是更新传递给它的位图(注意我代码中的最后三行)。

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

我没有测试过这段代码,所以不能保证这正是你所需要的,但这应该能让你开始。

于 2013-04-18T08:55:24.957 回答