You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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())
                    )
                }
            }
        }
    }
}

关键修改说明

  1. 修复编译错误:补充原代码未定义的shape变量,替换Canvas中写死的高度为参数imageHeight
  2. 适配逻辑实现:通过fitScale计算等比例缩放因子,避免图片拉伸或超出画布
  3. 居中处理:计算centerOffsetX/Y让缩放后的图片在画布内居中显示
  4. 视差整合:将视差偏移量与居中偏移量结合,保证滑动效果正常的同时图片仍适配画布

修改后,无论图片原始分辨率多大,都会等比例缩小至画布尺寸内完整显示,同时保留原有的视差滑动效果。

内容的提问来源于stack exchange,提问作者pepperlove

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 08:55:30