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

Kotlin+Jetpack绘制Bitmap时无法显示正确尺寸问题求助

问题排查与解决思路

你遇到的问题是:Bitmap和Canvas日志尺寸均为2312x1080,但绘制后图片底部和右侧被轻微截断。以下是几个常见原因及对应解决办法:

1. 系统栏Insets未正确消费

虽然你在Activity中开启了edge-to-edge模式,但Jetpack Compose默认不会自动忽略系统栏(状态栏、导航栏)的Insets,这会导致Canvas的实际可绘制区域被压缩,进而截断图片边缘。

解决:
在布局中添加consumeWindowInsets修饰符,让内容完全填充屏幕:

BoxWithConstraints(
    modifier = Modifier
        .fillMaxSize()
        .consumeWindowInsets(WindowInsets.systemBars)
) {
    // 原有代码
}

或者通过WindowInsets手动处理:

val windowInsets = rememberWindowInsets()
BoxWithConstraints(
    modifier = Modifier
        .fillMaxSize()
        .windowInsetsConsumed(windowInsets)
) {
    // 原有代码
}

2. Bitmap密度与设备不匹配

Bitmap的密度(density)如果和设备屏幕密度不一致,系统会自动缩放Bitmap。即使日志显示Bitmap尺寸是2312x1080,实际渲染时的像素大小可能已经被调整,导致边缘截断。

解决:
解码Bitmap时,强制匹配设备屏幕密度:

val bitmap = remember(screenshotPath) {
    if (!screenshotPath.isNullOrEmpty()) {
        val displayMetrics = context.resources.displayMetrics
        val options = BitmapFactory.Options().apply {
            inDensity = displayMetrics.densityDpi
            targetDensity = displayMetrics.densityDpi
            inScaled = true
        }
        BitmapFactory.decodeFile(screenshotPath, options)?.asImageBitmap()
    } else {
        null
    }
}

3. 绘制时未显式指定Canvas尺寸

使用drawImage只传topLeft参数时,默认用Bitmap原始尺寸绘制。如果Canvas实际尺寸和Bitmap存在微小像素差(比如布局舍入),就会导致边缘截断。

解决:
显式指定绘制尺寸为Canvas的大小:

Canvas(modifier = Modifier.fillMaxSize()) {
    bitmap?.let { image ->
        drawImage(
            image = image,
            topLeft = Offset.Zero,
            size = size // 用Canvas当前尺寸填充
        )
    }
}

快速验证方法

给Canvas画个红色边框,确认Canvas是否真的充满屏幕:

Canvas(modifier = Modifier.fillMaxSize()) {
    drawRect(Color.Red, style = Stroke(width = 2f))
    // 原有绘制代码
}

如果边框没充满屏幕,说明Insets处理有问题;如果边框充满但图片截断,就是Bitmap缩放或绘制尺寸的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 23:42:02