如何从手机截图生成的bitmap中裁剪status bar等系统栏区域
你的原有方案的问题在于硬编码了系统栏高度,不同设备的状态栏、导航栏高度存在差异,无法通用。正确方案是动态获取系统栏真实高度后再进行裁剪,实现逻辑如下:
1. 动态获取状态栏高度
fun getStatusBarHeight(context: Context): Int { var height = 0 val resId = context.resources.getIdentifier("status_bar_height", "dimen", "android") if (resId > 0) { height = context.resources.getDimensionPixelSize(resId) } return height }
2. 动态获取导航栏高度(自动适配手势导航场景)
fun getNavigationBarHeight(context: Context): Int { var height = 0 // 先判断设备是否开启了虚拟导航栏 val hasNavBarResId = context.resources.getIdentifier("config_showNavigationBar", "bool", "android") val hasNavBar = if (hasNavBarResId > 0) context.resources.getBoolean(hasNavBarResId) else false if (hasNavBar) { val resId = context.resources.getIdentifier("navigation_bar_height", "dimen", "android") if (resId > 0) { height = context.resources.getDimensionPixelSize(resId) } } return height }
3. 裁剪Bitmap逻辑
bitmap?.let { originBitmap -> val statusBarHeight = getStatusBarHeight(context) val navBarHeight = getNavigationBarHeight(context) // 校验裁剪高度合法性,避免触发参数异常 val cropHeight = originBitmap.height - statusBarHeight - navBarHeight if (cropHeight > 0) { cropimg = Bitmap.createBitmap( originBitmap, 0, statusBarHeight, // 裁剪起始Y坐标为状态栏高度 originBitmap.width, cropHeight ) // 不需要保留原图时可主动回收节省内存 originBitmap.recycle() } }
注意事项
- 如果截图包含ActionBar/Toolbar,可额外通过
context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.actionBarSize)).getDimensionPixelSize(0, 0)获取ActionBar高度,计算裁剪参数时对应减去即可 - 部分定制ROM导航栏显示逻辑特殊,如果出现适配问题可额外判断导航栏显示位置,对横屏/侧边导航场景做单独适配
- 裁剪前一定要校验计算后的裁剪高度大于0,避免出现
IllegalArgumentException异常
内容的提问来源于stack exchange,提问作者Mohammad Taqi Velani
相关产品推荐
相关产品推荐

