Android API 28及以下版本如何使用LIGHTEN、DARKEN、OVERLAY Porter-Duff模式
解决Android API 28及更低版本LIGHTEN/DARKEN/OVERLAY混合模式不生效问题
以下是三种可落地的实现方案,可结合你的需求选择:
方案1:绘制环节临时关闭硬件加速(适配成本最低)
不要全局关闭硬件加速避免性能损耗,仅在使用特殊混合模式的绘制流程中临时切换图层类型即可:
- 在
onDraw方法执行对应混合绘制前,调用setLayerType(LAYER_TYPE_SOFTWARE, yourPaint)切换为软件渲染 - 完成混合绘制逻辑后,调用
setLayerType(LAYER_TYPE_HARDWARE, null)切回硬件渲染 - 你现有的触摸移动Bitmap、调整Paint不透明度逻辑无需做任何修改,直接复用即可
方案2:基于GPUImage自定义混合滤镜(性能最优)
你可以直接基于已接入的GPUImage实现自定义混合逻辑,全程走硬件渲染无性能问题:
- 自定义GPUImage双输入滤镜,将当前画布内容和待混合的Bitmap作为两个纹理输入到片段着色器中
- 在着色器中手动实现三种混合模式的算法,核心逻辑参考:
- LIGHTEN:
gl_FragColor = max(baseTextureColor, blendBitmapColor); - DARKEN:
gl_FragColor = min(baseTextureColor, blendBitmapColor); - OVERLAY:
gl_FragColor = mix(2.0 * baseTextureColor * blendBitmapColor, 1.0 - 2.0 * (1.0 - baseTextureColor) * (1.0 - blendBitmapColor), step(0.5, baseTextureColor));
- LIGHTEN:
- 触摸移动Bitmap的逻辑通过调整混合Bitmap的纹理坐标实现,调整不透明度直接在着色器中对
blendBitmapColor乘alpha参数即可
方案3:离屏软绘缓存(兼顾性能与兼容性)
如果需要频繁使用这几种混合模式,可以用离屏缓存降低重复软绘的开销:
- 预先将需要应用特殊混合模式的元素,绘制到一个软件加速的离屏
Bitmap缓存中 - 后续直接将合成好的缓存Bitmap绘制到硬件加速的主Canvas上
- 触摸移动、调整不透明度的逻辑直接作用于这个缓存Bitmap的绘制参数即可
内容的提问来源于stack exchange,提问作者Nafia Mahjabin
相关产品推荐
相关产品推荐

