【问题标题】:Jetpack Compose Canvas BlendMode.SRC_IN makes even background transparentJetpack Compose Canvas BlendMode.SRC_IN 使背景变得透明
【发布时间】:2021-12-10 21:16:24
【问题描述】:

我正在尝试使用 BlendMode.SRC_IN 在 PNG 图像(具有透明背景)上添加叠加颜色,但背景变为黑色而不是设置的背景颜色,就好像也屏蔽了背景像素一样。

@Composable
fun Icon(
        fraction: Float,
        image: ImageAsset,
        defaultColor: Color = Color(0xFFEEEEEE),
        progressColor: Color = Color(0xFF888888),
        size: Dp = image.width.dp
) {
    Box(modifier = Modifier.size(size = size)) {
        Canvas(modifier = Modifier.fillMaxSize()) {
            drawImage(
                    image = image,
                    dstSize = IntSize(
                            width = size.toIntPx(),
                            height = size.toIntPx()
                    ),
                    colorFilter = ColorFilter.tint(
                            color = defaultColor
                    ),
                    blendMode = BlendMode.Src
            )
            drawIntoCanvas {
                val paint = Paint().apply {
                    color = progressColor
                    blendMode = BlendMode.SrcIn
                }

                it.restore()
                it.drawRect(
                        rect = Rect(
                                offset = Offset.Zero,
                                size = Size(
                                        width = size.toPx() * fraction,
                                        height = size.toPx()
                                )
                        ),
                        paint = paint
                )
                it.save()
            }
        }
    }
}

当我将多个Icon() 排在Screen(color = Color.WHITE) 之类的顶部时,效果如下,

Surface(color = Color.White) {
        Row {
            listOf(
                    R.drawable.anemo,
                    R.drawable.cryo,
                    R.drawable.dendro,
                    R.drawable.electro,
                    R.drawable.geo,
                    R.drawable.hydro,
                    R.drawable.pyro
            ).forEachIndexed { index, imageRes ->
                val from = 100f/7 * index
                val to = 100f/7 * (index + 1)
                val fraction = when {
                    progress > to -> 1f
                    progress > from -> (progress - from)/(to - from)
                    else -> 0f
                }
                Icon(
                        fraction = fraction,
                        image = imageResource(id = imageRes),
                        size = 50.dp
                )
            }
        }
    }

我想要的结果是,

我在这里做错了吗?

这是Github repository 我正在尝试的地方。

【问题讨论】:

  • 为什么在主视图中使用 Surface?如果您不想进行任何海拔处理?
  • 没有 Surface 也可以。但只是为了证明我面临的问题,即使 Surface 对背景颜色没有任何影响,我添加了它。

标签: android android-jetpack-compose


【解决方案1】:

在我的例子中,我可以通过添加 graphicsLayer 修饰符来解决黑色像素应该是透明像素的问题,如下所示:

Box(
    modifier = Modifier.fillMaxSize()
) {
    Canvas(modifier = Modifier
        .fillMaxSize()
        .graphicsLayer(alpha = 0.99f)
    ) {
        drawRect(
            color = Color.Black,
            size = size,
            blendMode = BlendMode.Xor
        )

        drawCircle(
            color = Color.Black,
            radius = 300f,
            blendMode = BlendMode.Xor
        )
    }
}

没有修饰符:

带修饰符:

我从这里得到了这个想法:https://gist.github.com/nadewad/14f04c788aea43bd6d31d94cd8100ab5(请注意,drawLayer 已重命名为 graphicsLayer

【讨论】:

    【解决方案2】:

    .graphicsLayer(alpha = 0.99f) 是一种有效的解决方法,但是,它会更改内容的 alpha 值,这是不必要的。

    要将绘图重定向到屏幕外渲染目标,可以使用android.graphics.Canvas#saveLayer(android.graphics.RectF, android.graphics.Paint),一个简单的修饰符可以是:

    fun Modifier.drawOffscreen(): Modifier = this.drawWithContent {
        with(drawContext.canvas.nativeCanvas) {
            val checkPoint = saveLayer(null, null)
            drawContent()
            restoreToCount(checkPoint)
        }
    }
    

    并且在调用restoreToCount 之前,内容将被绘制到屏幕外。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-22
      • 1970-01-01
      • 1970-01-01
      • 2022-12-18
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多