Как создать виджет обрезки изображения с помощью Jetpack Compose Canvas
Это моя первоначальная реализация. Любой, кто может помочь мне улучшить это, будет большим подспорьем.
Я пытаюсь создать виджет обрезки изображения с помощью Jetpack Compose. И я считаю, что для этого мне нужно использовать реактивный ранец для создания холста. Я сделал первую попытку, но застрял в той части, где мне нужно создать прямоугольник обрезки, перевести его на границы изображения, масштабировать с помощью жестов ввода, создавая эффект наложения темного изображения
Canvas(
modifier = Modifier
.fillMaxSize()
.scale(imageScale)
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
change.consumeAllChanges()
cropViewXPos += dragAmount.x
cropViewYPos += dragAmount.y
cropViewWidth = (finalWidth - change.position.x).toInt()
cropViewHeight = (finalHeight - change.position.y).toInt()
}
}
) {
val width: Int = bitmap.width
val height: Int = bitmap.height
val ratioBitmap = width.toFloat() / height.toFloat()
val ratioMax = size.width / size.height
finalWidth = size.width.toInt()
finalHeight = size.height.toInt()
if (ratioMax > ratioBitmap) {
finalWidth = (size.height * ratioBitmap).toInt()
} else {
finalHeight = (size.width / ratioBitmap).toInt()
}
offsetXImage = (size.width - finalWidth) / 2
offsetYImage = (size.height - finalHeight) / 2
drawImage(
image = bitmap.asImageBitmap(),
dstOffset = IntOffset(offsetXImage.toInt(), offsetYImage.toInt()),
dstSize = IntSize(finalWidth, finalHeight),
)
val gridLineColor = Color(0xFFE5E5E5)
val lineOffsetX = (finalWidth) / 6
val lineOffsetY = (finalHeight) / 6
val cropViewOffsetX = (cropViewWidth) / 6
val cropViewOffsetY = (cropViewHeight) / 6
// if (isPressingCropView) {
// for (i in 1..5 step 2) {
// val offsetHStart = Offset(
// x = offsetXImage,
// y = offsetYImage + i * lineOffsetY
// )
//
// val offsetHEnd = Offset(
// x = offsetXImage + finalWidth,
// y = offsetYImage + i * lineOffsetY
// )
//
// val offsetVStart = Offset(
// x = offsetXImage + i * lineOffsetX,
// y = offsetYImage
// )
//
// val offsetVEnd = Offset(
// x = offsetXImage + i * lineOffsetX,
// y = offsetYImage + finalHeight
// )
//
// drawLine(
// color = gridLineColor,
// offsetHStart,
// offsetHEnd,
// strokeWidth = 1.dp.toPx(),
// cap = StrokeCap.Round
// )
// drawLine(
// color = gridLineColor,
// offsetVStart,
// offsetVEnd,
// strokeWidth = 1.dp.toPx(),
// cap = StrokeCap.Round
// )
// }
// }
//
// for (i in 2..4 step 2) {
// val offsetHStart = Offset(
// x = offsetXImage,
// y = offsetYImage + i * cropViewOffsetY
// )
//
// val offsetHEnd = Offset(
// x = offsetXImage + cropViewWidth,
// y = offsetYImage + i * cropViewOffsetY
// )
//
// val offsetVStart = Offset(
// x = offsetXImage + i * cropViewOffsetX,
// y = offsetYImage
// )
//
// val offsetVEnd = Offset(
// x = offsetXImage + i * cropViewOffsetX,
// y = offsetYImage + cropViewHeight
// )
//
// drawLine(
// color = gridLineColor,
// offsetHStart,
// offsetHEnd,
// strokeWidth = 1.dp.toPx(),
// cap = StrokeCap.Round
// )
// drawLine(
// color = gridLineColor,
// offsetVStart,
// offsetVEnd,
// strokeWidth = 1.dp.toPx(),
// cap = StrokeCap.Round
// )
// }
drawRect(
color = Color.White,
topLeft = Offset(cropViewXPos, cropViewYPos),
size = Size(cropViewWidth.toFloat(), cropViewHeight.toFloat()),
style = Stroke(2.dp.toPx())
)
}