如何在Jetpack Compose Canvas中让图片完美适配画布尺寸绘制?
解决Jetpack Compose Canvas图片适配画布问题
实现思路
要让图片完美适配Canvas宽高,核心是计算图片与画布的等比例缩放因子,确保图片按比例缩放到画布尺寸内,同时保留原有的视差偏移效果:
- 获取画布实际像素尺寸与图片原始像素尺寸
- 计算宽、高方向的缩放比例,取最小值作为适配因子(保证图片完整显示无拉伸)
- 基于缩放因子调整图片绘制尺寸,再计算居中偏移量让图片在画布内居中
- 整合视差偏移量,确保滑动效果正常
修改后的完整代码
@Composable fun Item( imageResId: Int, parallaxOffset: Float, pagerHeight: Dp, screenWidth: Dp, density: Float, scaleFactor: Float, modifier: Modifier = Modifier, imageCornerRadius: Dp = 24.dp, imageHeight: Dp = 250.dp, ) { val imageBitmap = ImageBitmap.imageResource(id = imageResId) val shape = RoundedCornerShape(imageCornerRadius) Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Box(modifier = modifier .graphicsLayer { scaleX = scaleFactor scaleY = scaleFactor } .clip(shape)) { Canvas( modifier = Modifier .fillMaxWidth() .height(imageHeight) .clip(shape) ) { // 获取画布与图片的像素尺寸 val canvasWidth = size.width val canvasHeight = size.height val imgWidth = imageBitmap.width.toFloat() val imgHeight = imageBitmap.height.toFloat() // 计算等比例缩放因子,确保图片完整适配画布 val scaleX = canvasWidth / imgWidth val scaleY = canvasHeight / imgHeight val fitScale = minOf(scaleX, scaleY) // 计算缩放后图片的尺寸 val scaledImgWidth = imgWidth * fitScale val scaledImgHeight = imgHeight * fitScale // 计算图片居中的偏移量 val centerOffsetX = (canvasWidth - scaledImgWidth) / 2f val centerOffsetY = (canvasHeight - scaledImgHeight) / 2f translate(left = parallaxOffset * density + centerOffsetX) { drawImage( image = imageBitmap, dstSize = IntSize(scaledImgWidth.toInt(), scaledImgHeight.toInt()), dstOffset = IntOffset(0, centerOffsetY.toInt()) ) } } } } }
关键修改说明
- 修复编译错误:补充原代码未定义的
shape变量,替换Canvas中写死的高度为参数imageHeight - 适配逻辑实现:通过
fitScale计算等比例缩放因子,避免图片拉伸或超出画布 - 居中处理:计算
centerOffsetX/Y让缩放后的图片在画布内居中显示 - 视差整合:将视差偏移量与居中偏移量结合,保证滑动效果正常的同时图片仍适配画布
修改后,无论图片原始分辨率多大,都会等比例缩小至画布尺寸内完整显示,同时保留原有的视差滑动效果。
内容的提问来源于stack exchange,提问作者pepperlove
相关产品推荐
相关产品推荐

