Android中RenderScript模糊代码已废弃,求高效GPU替代重写方案
替代RenderScript的Bitmap GPU模糊方案
一、RenderEffect直接处理Bitmap(Android 12+)
RenderEffect并非只能绑定ImageView,可通过离屏Canvas将模糊效果直接应用到Bitmap上,完全GPU加速,性能对标RenderScript。
代码示例:
private Bitmap blurBitmapWithRenderEffect(Bitmap source, int blurRadius) { // 限制模糊半径在RenderEffect允许的0-25范围内 float radius = Math.max(0f, Math.min(blurRadius, 25f)); // 创建模糊效果 RenderEffect blurEffect = RenderEffect.createBlurEffect(radius, radius, Shader.TileMode.CLAMP); // 创建输出Bitmap,复用原Bitmap的配置 Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig()); Canvas canvas = new Canvas(output); // 用带模糊效果的画笔绘制原Bitmap Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setRenderEffect(blurEffect); canvas.drawBitmap(source, 0, 0, paint); return output; }
替换原RenderScript逻辑的调用方式:
private void processImage(int value) { try { Bitmap blurredBitmap = blurBitmapWithRenderEffect(bitmap, value); blurredBitmap.getPixels(bitmap, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight()); blurredBitmap.recycle(); } catch (Exception e) { e.printStackTrace(); } }
二、OpenGL ES实现高性能模糊(全版本兼容)
如果需要兼容Android 12以下系统,OpenGL ES是性能最优的GPU方案,通过高斯模糊着色器和帧缓冲实现:
核心步骤:
- 加载高斯模糊的顶点/片段着色器
- 将原Bitmap转为OpenGL纹理
- 使用帧缓冲分两次渲染(横向+纵向模糊,优化效果与性能)
- 将渲染结果读取为新Bitmap
简化核心代码片段:
// 高斯模糊片段着色器(双向模糊优化) private static final String BLUR_FRAGMENT = """ precision mediump float; uniform sampler2D u_texture; uniform vec2 u_offset; uniform float u_weights[5]; uniform vec2 u_resolution; void main() { vec2 uv = gl_FragCoord.xy / u_resolution; vec4 color = vec4(0.0); color += texture2D(u_texture, uv - 2.0 * u_offset) * u_weights[0]; color += texture2D(u_texture, uv - 1.0 * u_offset) * u_weights[1]; color += texture2D(u_texture, uv) * u_weights[2]; color += texture2D(u_texture, uv + 1.0 * u_offset) * u_weights[1]; color += texture2D(u_texture, uv + 2.0 * u_offset) * u_weights[0]; gl_FragColor = color; } """; // 省略OpenGL上下文初始化、纹理上传、帧缓冲渲染逻辑 // 最终通过glReadPixels将帧缓冲数据写入Bitmap
该方案需要手动管理OpenGL资源,但性能远高于RenderScript,适合批量处理或大尺寸Bitmap场景。
三、第三方库快速实现
若不想手动实现底层逻辑,可使用Glide的模糊变换,自动适配系统版本选择最优GPU方案:
// 依赖Glide:implementation 'com.github.bumptech.glide:glide:4.16.0' private Bitmap blurWithGlide(Context context, Bitmap source, int radius) { try { return Glide.with(context) .asBitmap() .load(source) .transform(new BlurTransformation(radius)) .submit() .get(); } catch (Exception e) { return source; } }
关键注意点
- RenderEffect的模糊半径上限为25,超出会被系统自动截断,需提前做范围校验
- OpenGL方案需注意纹理尺寸兼容性(部分设备要求尺寸为2的幂次)
- 处理大Bitmap时,建议先缩小比例再模糊,最后放大,可大幅降低GPU负载
内容的提问来源于stack exchange,提问作者angel_30
相关产品推荐
相关产品推荐

