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

Compose中如何正确实现Bitmap围绕屏幕中心旋转并裁剪

正确实现围绕屏幕中心旋转并裁剪超出部分的方法

你的问题出在提前修改Bitmap的方式不符合Compose的布局逻辑:你直接基于屏幕尺寸裁剪Bitmap,且旋转中心的计算没结合图片自身尺寸,导致旋转位置偏离屏幕中心。在Compose里,更推荐在绘制阶段处理旋转和裁剪,而非提前修改Bitmap。

方法一:用Modifier快速实现(首推)

如果只是简单的旋转+裁剪,直接用Compose的Modifier.rotate配合布局裁剪就行,代码简洁易懂:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TestTheme {
                Box(
                    modifier = Modifier.fillMaxSize(),
                    contentAlignment = Alignment.Center
                ) {
                    val imageBitmap = BitmapFactory.decodeResource(resources, R.raw.photo)
                        .asImageBitmap()
                    
                    // 围绕屏幕中心旋转,超出屏幕的部分自动被裁剪
                    Image(
                        bitmap = imageBitmap,
                        contentDescription = null,
                        modifier = Modifier
                            .fillMaxSize() // 让图片填满布局,超出部分被裁剪
                            .rotate(45f), // 旋转45度,因为fillMaxSize,自身中心就是屏幕中心
                        contentScale = ContentScale.Crop // 确保图片铺满布局
                    )
                }
            }
        }
    }
}

方法二:用Canvas手动控制(适合复杂需求)

如果需要更精细的控制,比如自定义裁剪区域或旋转逻辑,可以在Canvas里直接处理:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TestTheme {
                Box(modifier = Modifier.fillMaxSize()) {
                    val imageBitmap = BitmapFactory.decodeResource(resources, R.raw.photo)
                        .asImageBitmap()
                    
                    Canvas(modifier = Modifier.fillMaxSize()) {
                        // 获取屏幕中心坐标
                        val screenCenter = Offset(size.width / 2, size.height / 2)
                        
                        // 保存画布状态,旋转后恢复
                        with(save()) {
                            // 围绕屏幕中心旋转画布
                            rotate(45f, pivot = screenCenter)
                            
                            // 计算图片绘制位置:让图片中心和屏幕中心对齐
                            val drawOffset = Offset(
                                screenCenter.x - imageBitmap.width / 2f,
                                screenCenter.y - imageBitmap.height / 2f
                            )
                            
                            // 绘制图片,超出屏幕的部分会被Canvas自动裁剪
                            drawImage(imageBitmap, topLeft = drawOffset)
                        }
                    }
                }
            }
        }
    }
}

原代码问题拆解

  1. 旋转中心计算错误:你的rotate函数用屏幕中心作为旋转中心,但创建Bitmap时强制把原图片缩放到屏幕尺寸,导致图片被拉伸/压缩,旋转后的位置自然不对。
  2. 绘制逻辑偏差:修改后的Bitmap直接从(0,0)绘制,没有和屏幕中心对齐,所以看起来旋转中心偏离预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:28:20