private void blur(Bitmap bkg, View view, float radius) {
Bitmap overlay = Bitmap.createBitmap(view.getMeasuredWidth(),
view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(overlay);
canvas.drawBitmap(bkg, -view.getLeft(), -view.getTop(), null);
RenderScript rs = RenderScript.create(this);
Allocation overlayAlloc = Allocation.createFromBitmap(rs, overlay);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, overlayAlloc.getElement());
blur.setInput(overlayAlloc);
blur.setRadius(radius); // 0 < radius <= 25
blur.forEach(overlayAlloc);
overlayAlloc.copyTo(overlay);
view.setBackground(new BitmapDrawable(getResources(), overlay));
rs.destroy();
}
優點:GPU 加速、極快、代碼簡潔。
缺點:需 API 17+(Android 4.2+),舊設備不支持。
基於 Mario Klingemann 的 Stack Blur 算法,介於高斯模糊與盒模糊之間,速度比高斯模糊快 7 倍。
public Bitmap fastblur(Bitmap sentBitmap, int radius) {
if (radius < 1) return null;
Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
int w = bitmap.getWidth(), h = bitmap.getHeight();
int[] pix = new int[w * h];
bitmap.getPixels(pix, 0, w, 0, 0, w, h);
// 核心模糊邏輯(約 200 行),包含水平垂直兩次掃描
// 使用移動棧維護顏色窗口,O(1) 更新均值
// 詳細代碼見原文,此處省略核心循環
bitmap.setPixels(pix, 0, w, 0, 0, w, h);
return bitmap;
}
優點:無版本限制、純 Java 實現。
缺點:CPU 計算耗時,大圖建議縮放後處理或放入後台線程。
| 指標 | RenderScript | Stack Blur |
|---|---|---|
| 1080p 圖片 radius=15 | ~15ms | ~300ms |
| 最低 API | 17 | 1 |
| 內存佔用 | 額外 Allocation | 像素數組 |
Build.VERSION.SDK_INT >= 17 動態選擇方案RxJava/Coroutine 後台線程,避免阻塞 UI