1

I am trying to create an Image cropping widget with Jetpack Compose. And I believe I have to use Canvas for this. I made an initial attempt but I am stuck on the part where I have to create the cropping rectangle, translating it on image bounds, scaling it with input gestures making the dark image overlay effect

Expected Result:

My Result:

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())
    )


}
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
YMS98
  • 26
  • 1
  • 2

0 Answers0