You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中如何直接为Bitmap添加模糊效果?求替代ImageView的方案

直接对Bitmap添加模糊效果的几种方案

一、API 31+ 使用RenderEffect(官方推荐)

你之前用的RenderEffect不仅能作用于View,也可以通过Canvas直接应用到Bitmap上。drawToBitmap()拿不到View应用RenderEffect后的Bitmap,是因为RenderEffect属于View渲染阶段的临时效果,不会修改底层原始Bitmap。可以通过创建新Bitmap,在Canvas上绘制原Bitmap时叠加模糊效果:

private fun blurBitmapApi31Plus(originalBitmap: Bitmap, radius: Float): Bitmap {
    val blurredBitmap = Bitmap.createBitmap(originalBitmap.width, originalBitmap.height, originalBitmap.config)
    val canvas = Canvas(blurredBitmap)
    val renderEffect = RenderEffect.createBlurEffect(radius, radius, Shader.TileMode.CLAMP)
    
    canvas.save()
    canvas.setRenderEffect(renderEffect)
    canvas.drawBitmap(originalBitmap, 0f, 0f, null)
    canvas.restore()
    
    return blurredBitmap
}

调用时直接传入原Bitmap和模糊半径即可,这个方案和你之前的View模糊逻辑一致,属于官方现代API。

二、兼容低版本:RenderScript实现

RenderScript可以高效实现Bitmap模糊,虽然API 31+被标记为废弃,但依然可以正常使用,也能通过AndroidX的RenderScript库兼容更低版本:

1. 依赖配置(AndroidX版本)

在Module级别的build.gradle中添加:

android {
    defaultConfig {
        renderscriptTargetApi 33
        renderscriptSupportModeEnabled true
    }
}

2. 模糊实现代码

private fun blurBitmapWithRenderScript(context: Context, originalBitmap: Bitmap, radius: Float): Bitmap {
    val rs = RenderScript.create(context)
    val input = Allocation.createFromBitmap(rs, originalBitmap)
    val output = Allocation.createTyped(rs, input.type)
    val blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))
    
    blurScript.setInput(input)
    blurScript.setRadius(radius.coerceIn(0.1f, 25f)) // RenderScript模糊半径限制在0.1-25之间
    blurScript.forEach(output)
    
    val bitmapCopy = originalBitmap.copy(originalBitmap.config, true)
    output.copyTo(bitmapCopy)
    
    rs.destroy()
    return bitmapCopy
}

注:这里创建了原Bitmap的副本进行处理,避免修改原始Bitmap对象。

三、替代方案:自定义高斯模糊算法(不推荐)

如果不想依赖RenderScript或高版本API,也可以手动实现高斯模糊算法,但效率远低于前两种方案,仅适合小尺寸Bitmap:

// 简化版高斯模糊实现,仅作示例
private fun blurBitmapManual(originalBitmap: Bitmap, radius: Int): Bitmap {
    val width = originalBitmap.width
    val height = originalBitmap.height
    val pixels = IntArray(width * height)
    originalBitmap.getPixels(pixels, 0, width, 0, 0, width, height)
    
    val blurRadius = radius.coerceAtMost(25)
    val kernelSize = blurRadius * 2 + 1
    val kernel = FloatArray(kernelSize)
    val sigma = blurRadius / 3.0f
    var sum = 0f

    // 构建高斯核
    for (i in 0 until kernelSize) {
        kernel[i] = Math.exp(-((i - blurRadius) * (i - blurRadius)) / (2 * sigma * sigma)).toFloat()
        sum += kernel[i]
    }
    // 归一化核
    for (i in kernel.indices) kernel[i] /= sum

    // 横向模糊
    val tempPixels = IntArray(width * height)
    for (y in 0 until height) {
        for (x in 0 until width) {
            var r = 0f
            var g = 0f
            var b = 0f
            for (k in 0 until kernelSize) {
                val neighborX = x + k - blurRadius
                if (neighborX in 0 until width) {
                    val pixel = pixels[y * width + neighborX]
                    r += Color.red(pixel) * kernel[k]
                    g += Color.green(pixel) * kernel[k]
                    b += Color.blue(pixel) * kernel[k]
                }
            }
            tempPixels[y * width + x] = Color.rgb(r.toInt(), g.toInt(), b.toInt())
        }
    }

    // 纵向模糊
    for (x in 0 until width) {
        for (y in 0 until height) {
            var r = 0f
            var g = 0f
            var b = 0f
            for (k in 0 until kernelSize) {
                val neighborY = y + k - blurRadius
                if (neighborY in 0 until height) {
                    val pixel = tempPixels[neighborY * width + x]
                    r += Color.red(pixel) * kernel[k]
                    g += Color.green(pixel) * kernel[k]
                    b += Color.blue(pixel) * kernel[k]
                }
            }
            pixels[y * width + x] = Color.rgb(r.toInt(), g.toInt(), b.toInt())
        }
    }

    val blurredBitmap = Bitmap.createBitmap(width, height, originalBitmap.config)
    blurredBitmap.setPixels(pixels, 0, width, 0, 0, width, height)
    return blurredBitmap
}

四、第三方库方案

如果不想自己实现,也可以使用成熟的第三方库,比如Glide的BlurTransformation,只需在加载Bitmap时添加转换即可,不过需要引入Glide依赖。


内容的提问来源于stack exchange,提问作者thebluepandabear

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 13:50:20