Android 12 Canvas调用drawPoint()存在无法消除的Paint透明度问题
问题根因
Android 12(API 31)对Canvas绘制逻辑做了调整,默认启用亚像素定位,搭配Paint抗锯齿配置时,drawPoint绘制的点会自动和底层像素做半透明混合,哪怕显式设置alpha=255也会出现颜色偏浅的问题。
最优解决方案(性能高于逐点setPixel)
无需修改现有绘制逻辑,仅调整Paint初始化配置即可:
private val foregroundPaint: Paint by lazy { Paint().apply { // 绘制精确像素点无需抗锯齿,直接关闭避免边缘半透明 isAntiAlias = false // 设置混合模式为SRC,绘制内容直接覆盖目标像素,不做任何混合计算 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { blendMode = BlendMode.SRC } else { @Suppress("DEPRECATION") xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC) } color = Color.BLACK } }
如果业务必须保留抗锯齿,可将绘制坐标偏移0.5像素,让点刚好落在像素中心即可避免半透明:
canvas.drawPoint( x.toFloat() + 0.5f, y.toFloat() + 0.5f, foregroundPaint )
方案对比
- 上述Paint配置方案性能和原有绘制逻辑一致,无需修改遍历代码,兼容性更优
- 你当前使用的
setPixel方案仅适合小范围绘制场景,当绘制区域较大时,性能比Canvas绘制低30%以上
内容的提问来源于stack exchange,提问作者Toby
相关产品推荐
相关产品推荐

