I am developing an Android application in Kotlin using Jetpack Compose, where users can upload an image, move it around (including zooming in by pinching with two fingers), and get the color of the pixel at the point of touch on the image.
However, I am encountering an issue when moving the loaded image from left to right (horizontally) within a Box.
The offset (offset.x - topLeftX) seems to increase disproportionately with the actual movement of the image on the screen. I've logged the offset change using Log.d("Coordinates", "offset.x - topLeftX: ${(offset.x - topLeftX).toString()}") and the values do not remain constant as expected when moving the image only horizontally.
Box(
contentAlignment = Alignment.TopCenter,
modifier = Modifier.fillMaxSize()
.padding(start = Dp(10.0F), top = Dp(60F), end = Dp(10F), bottom = Dp(10F))
.border(BorderStroke(2.dp, Color.Black)) // Creates a border
.clip(RoundedCornerShape(10.dp)) // Clips content to the shape
.pointerInput(Unit) {
detectTransformGestures { centroid, pan, zoom, rotation ->
offsetX += pan.x
offsetY += pan.y
topLeftCorner = Pair(offsetX, offsetY)
Log.d("Zoom", zoom.toString())
Log.d("Coordinates", "Top Left Corner: $topLeftCorner")
}
}
.pointerInput(Unit) {
detectTapGestures(onLongPress = { offset ->
touchLocation = Pair(offset.x, offset.y)
val topLeftX = topLeftCorner?.first ?: 0f
val topLeftY = topLeftCorner?.second ?: 0f
val relativeX = offset.x
val relativeY = offset.y
bitmap?.let {bitmap ->
val bitmapX = (offset.x / bitmap.width * bitmap.width).toInt()
val bitmapY = (offset.y / bitmap.height * bitmap.height).toInt()
if(bitmapX > 0 && bitmapY > 0){
var pixelColor = bitmap.getPixel(bitmapX, bitmapY)
pointColor = bitmap.getPixel(bitmapX, bitmapY).toComposeColor()
val hexColor = String.format("#%06X", (0xFFFFFF and pixelColor))
Log.d("ColorPicker", "Picked color: $hexColor")
Log.d("Coordinates", "Top Left Corner FromBoxOffsetToLeftCorner: $topLeftCorner")
Log.d("Coordinates", "Top Left Corner Offset: $touchLocation")
Log.d("Coordinates", "offset.x - topLeftX: ${(offset.x - topLeftX).toString()}")
val width = size.width
val bitmapWidth = bitmap.width
Log.d("Coordinates", "Size.width: $width; bitmap.width: $bitmapWidth")
pickedColor = hexColor
showDialog = true
}
Log.d("Coordinates", "Touch LOCATION: $bitmapX; $bitmapY")
}
})
}
){
bitmap?.let { bitmap ->
Image(
bitmap = bitmap.asImageBitmap(),
contentDescription = "Picked Image",
modifier = Modifier
.fillMaxWidth()
.scale(scale)
.rotate(rotationState)
.absoluteOffset(x = Dp(offsetX), y = Dp(offsetY)),
contentScale = ContentScale.FillBounds
)
}
Could someone please help me understand what I'm doing wrong here? Why is the offset not scaling proportionally with the image movement?