Android Compose Canvas 产生意外的 BlendMode 结果

问题描述 投票:0回答:1

我希望将图像裁剪大约一个圆的象限以获得以下效果:

我最初的想法是在使用

BlendMode
Canvas
中使用
drawWithContent
。但是,我发现我尝试过的所有
BlendMode
要么只显示方形图像,要么显示上面画有不透明圆圈的方形图像。例如,对于
dstIn
srcIn
,我看到:

源代码:

GlideImage(
    modifier = Modifier
        .requiredSize(158.dp)
        .graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen)
        .drawWithContent {
            val radius = size.width - 28.dp.toPx()
            drawContent()
            drawCircle(
                blendMode = BlendMode.DstIn,
                color = Color.Transparent,
                radius = radius,
                center = Offset(radius, radius),
            )
        },
    contentScale = ContentScale.Crop,
    model = persona.imageUrl,
    contentDescription = null,
)

对我缺少的东西有什么想法吗?

android android-jetpack-compose android-canvas android-jetpack-compose-canvas
1个回答
0
投票

它不起作用的原因是您将混合模式应用于仅可用于圈出而不是所有像素的区域。因此,它不会仅应用于图像和圆相交的地方。

如果您能够使用 Painter 或 ImageBitmap 绘制图像,您可以这样做

@Preview
@Composable
private fun BlendModeSample() {
    Column(
        modifier = Modifier.padding(20.dp)
    ) {

        val image = ImageBitmap.imageResource(R.drawable.landscape1)

        Canvas(
            modifier = Modifier
                .size(135.dp)
                .graphicsLayer {
                    compositingStrategy = CompositingStrategy.Offscreen
                }
        ) {
            val radius = size.width - 28.dp.toPx()

            drawCircle(
                color = Color.Red,
                radius = radius,
                center = Offset(radius, radius),
            )

            drawImage(
                image,
                dstSize = IntSize(size.width.toInt(), size.height.toInt()),
                blendMode = BlendMode.SrcIn)
        }
    }
}

如果这不是一个选项,您可以将矩形和圆形与路径相交,并使用该形状作为混合模式

@Preview
@Composable
private fun BlendModeTest() {
    Column(
        modifier = Modifier.padding(20.dp)
    ) {
        Image(
            modifier = Modifier
                .size(135.dp)
                .graphicsLayer {
                    compositingStrategy = CompositingStrategy.Offscreen
                }
                .drawWithCache {

                    val radius = size.width - 28.dp.toPx()
                    val path = Path()
                    val pathCircle = Path()

                    if (path.isEmpty) {
                        path.addRect(
                            Rect(
                                offset = Offset.Zero,
                                size = size
                            )
                        )

                    }

                    if (pathCircle.isEmpty) {
                        pathCircle.addOval(
                            Rect(
                                center = Offset(
                                    radius, radius
                                ),
                                radius = radius
                            )
                        )
                    }

                    path.op(path, pathCircle, PathOperation.Difference)

                    onDrawWithContent {
                        drawContent()
                        drawPath(path, Color.Transparent, blendMode = BlendMode.DstIn)

                    }
                },
            painter = painterResource(R.drawable.landscape2),
            contentScale = ContentScale.Crop,
            contentDescription = null
        )
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.