Jetpack Compose Canvas BlendMode.SRC_IN 使背景变得透明 [英] Jetpack Compose Canvas BlendMode.SRC_IN makes even background transparent
问题描述
我正在尝试使用 BlendMode.SRC_IN 在 PNG 图像(具有透明背景)之上添加叠加颜色,但背景变为黑色而不是设置的背景颜色,就像掩盖了背景像素一样.
@Composable有趣的图标(分数:浮动,图像:ImageAsset,默认颜色:颜色 = 颜色(0xFFEEEEEE),progressColor: 颜色 = 颜色(0xFF888888),尺寸:dp = image.width.dp){Box(modifier = Modifier.size(size = size)) {画布(修饰符 = Modifier.fillMaxSize()){绘制图像(图像 = 图像,dstSize = IntSize(宽度 = size.toIntPx(),高度 = size.toIntPx()),颜色过滤器 = 颜色过滤器.tint(颜色 = 默认颜色),blendMode = BlendMode.Src)drawIntoCanvas {val 油漆 = 油漆().应用{颜色 = 进度颜色blendMode = BlendMode.SrcIn}it.restore()it.drawRect(矩形 = 矩形(偏移量 = 偏移量.零,尺寸 = 尺寸(宽度 = size.toPx() * 分数,高度 = size.toPx())),油漆 = 油漆)保存()}}}}
这是我在 Screen(color = Color.WHITE)
顶部排列多个 Icon()
时的样子,
表面(颜色 = Color.White){排 {清单(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 * 索引val to = 100f/7 * (index + 1)val 分数 = 当 {进展>到->1楼进展>从 ->(进度 - 从)/(到 - 从)否则 ->0f}图标(分数 = 分数,图像 = imageResource(id = imageRes),尺寸 = 50.dp)}}}
我想要的结果是,
我在这里做错了吗?
这是我正在尝试的
带修饰符:
我从这里得到了这个想法:https://gist.github.com/nadewad/14f04c788aea43bd6d31d94cd8100ab5"/a>(注意 drawLayer
被重命名为 graphicsLayer
.
I'm trying to add an overlay color on top of a PNG image (with a transparent background) using BlendMode.SRC_IN but the background becomes black instead of the set background color as if masking out the background pixels as well.
@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()
}
}
}
}
Here is how it looks when I line up multiple Icon()
on top of a Screen(color = Color.WHITE)
like,
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
)
}
}
}
The desired result I want is,
Am I doing something wrong here?
Here is the Github repository where I'm trying this out.
In my case, I could solve the issue of having black pixels where they should be transparent pixels by adding the graphicsLayer
modifier like this:
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
)
}
}
Without the modifier:
With modifier:
I took that idea from here: https://gist.github.com/nadewad/14f04c788aea43bd6d31d94cd8100ab5 (note that drawLayer
was renamed to graphicsLayer
.
这篇关于Jetpack Compose Canvas BlendMode.SRC_IN 使背景变得透明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!