gpt4 book ai didi

android - 如何在 Jetpack Compose 中删除 Canvas 时变得透明,现在我变成了白色?

转载 作者:行者123 更新时间:2023-12-05 03:21:13 26 4
gpt4 key购买 nike

如何使 Canvas 的某些部分透明?我希望用户能够像这样删除照片的一部分 link显示为透明。我的 Canvas 代码:

Canvas(
modifier = modifier
.background(Color.Transparent)
) {
with(drawContext.canvas.nativeCanvas) {
val checkPoint = saveLayer(null, null)
drawImage(
image = bitmap,
srcSize = IntSize(bitmap.width, bitmap.height),
dstSize = IntSize(canvasWidth, canvasHeight)
)
drawPath(
path = erasePath,
style = Stroke(
width = 30f,
cap = StrokeCap.Round,
join = StrokeJoin.Round
),
blendMode = BlendMode.Clear,
color = Color.Transparent,
)
restoreToCount(checkPoint)
}
}

最佳答案

你得到的透明是 Color(0x00000000),你得到的白色是你背景的颜色,即使你的 Canvas 有透明背景,你的根或父 Composable 的颜色是白色。

您需要先绘制棋盘格布局或棋盘格图像,在层内您应该使用 BlendMode.Clear 绘制图像和路径

val width = this.size.width
val height = this.size.height

val checkerWidth = 10.dp.toPx()
val checkerHeight = 10.dp.toPx()

val horizontalSteps = (width / checkerWidth).toInt()
val verticalSteps = (height / checkerHeight).toInt()

for (y in 0..verticalSteps) {
for (x in 0..horizontalSteps) {
val isGrayTile = ((x + y) % 2 == 1)
drawRect(
color = if (isGrayTile) Color.LightGray else Color.White,
topLeft = Offset(x * checkerWidth, y * checkerHeight),
size = Size(checkerWidth, checkerHeight)
)
}
}

val space = 20.dp.roundToPx()

with(drawContext.canvas.nativeCanvas) {
val checkPoint = saveLayer(null, null)

// Destination
drawImage(
image = dstBitmap,
dstOffset = IntOffset(
space / 2,
space / 2
),
dstSize = IntSize(
canvasWidth - space, canvasHeight - space
)
)

// Source
drawPath(
color = Color.Transparent,
path = erasePath,
style = Stroke(
width = 30f,
cap = StrokeCap.Round,
join = StrokeJoin.Round
),
blendMode = BlendMode.Clear
)
restoreToCount(checkPoint)
}

完整实现

@Composable
private fun MyImageDrawer(modifier: Modifier) {

// This is the image to draw onto
val dstBitmap = ImageBitmap.imageResource(id = R.drawable.landscape1)


// Path used for erasing. In this example erasing is faked by drawing with canvas color
// above draw path.
val erasePath = remember { Path() }

var motionEvent by remember { mutableStateOf(MotionEvent.Idle) }
// This is our motion event we get from touch motion
var currentPosition by remember { mutableStateOf(Offset.Unspecified) }
// This is previous motion event before next touch is saved into this current position
var previousPosition by remember { mutableStateOf(Offset.Unspecified) }


val drawModifier = modifier
.pointerMotionEvents(Unit,
onDown = { pointerInputChange ->
motionEvent = MotionEvent.Down
currentPosition = pointerInputChange.position
pointerInputChange.consume()
},
onMove = { pointerInputChange ->
motionEvent = MotionEvent.Move
currentPosition = pointerInputChange.position
pointerInputChange.consume()
},
onUp = { pointerInputChange ->
motionEvent = MotionEvent.Up
pointerInputChange.consume()
}
)

Canvas(modifier = drawModifier) {

val canvasWidth = size.width.roundToInt()
val canvasHeight = size.height.roundToInt()

// Draw or erase depending on erase mode is active or not

when (motionEvent) {

MotionEvent.Down -> {
erasePath.moveTo(currentPosition.x, currentPosition.y)
previousPosition = currentPosition

}
MotionEvent.Move -> {

erasePath.quadraticBezierTo(
previousPosition.x,
previousPosition.y,
(previousPosition.x + currentPosition.x) / 2,
(previousPosition.y + currentPosition.y) / 2

)
previousPosition = currentPosition
}

MotionEvent.Up -> {
erasePath.lineTo(currentPosition.x, currentPosition.y)
currentPosition = Offset.Unspecified
previousPosition = currentPosition
motionEvent = MotionEvent.Idle
}
else -> Unit
}


val width = this.size.width
val height = this.size.height

val checkerWidth = 10.dp.toPx()

val checkerHeight = 10.dp.toPx()

val horizontalSteps = (width / checkerWidth).toInt()
val verticalSteps = (height / checkerHeight).toInt()

for (y in 0..verticalSteps) {
for (x in 0..horizontalSteps) {
val isGrayTile = ((x + y) % 2 == 1)
drawRect(
color = if (isGrayTile) Color.LightGray else Color.White,
topLeft = Offset(x * checkerWidth, y * checkerHeight),
size = Size(checkerWidth, checkerHeight)
)
}
}

val space = 20.dp.roundToPx()

with(drawContext.canvas.nativeCanvas) {
val checkPoint = saveLayer(null, null)

// Destination
drawImage(
image = dstBitmap,
dstOffset = IntOffset(
space / 2,
space / 2
),
dstSize = IntSize(
canvasWidth - space, canvasHeight - space
)
)

// Source
drawPath(
color = Color.Transparent,
path = erasePath,
style = Stroke(
width = 30f,
cap = StrokeCap.Round,
join = StrokeJoin.Round
),
blendMode = BlendMode.Clear
)
restoreToCount(checkPoint)
}
}
}

结果

enter image description here

关于android - 如何在 Jetpack Compose 中删除 Canvas 时变得透明,现在我变成了白色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73023593/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com