Android中使用U2Net模型获取裁剪图像Bitmap的问题咨询
问题解决方法
核心问题原因
你遇到的问题由两个核心原因导致:
- 掩码缺失有效Alpha通道:你生成灰度掩码时使用了
Color.rgb()方法,该方法生成的颜色默认Alpha通道值为255(完全不透明)。而PorterDuff.Mode.DST_IN模式依靠掩码的Alpha通道值判断保留区域,全不透明的Alpha通道会导致整张原图都被保留。 - 冗余代码可能引发渲染异常。
修改方案
第一步:修改灰度掩码生成函数
将Color.rgb()替换为Color.argb(),把灰度值同时赋值给Alpha通道,让掩码的透明程度和灰度值匹配:
fun convertArrayToBitmapTensorFlow( imageArray: Array<Array<Array<FloatArray>>>, imageWidth: Int, imageHeight: Int ): Bitmap { val conf = Bitmap.Config.ARGB_8888 val grayToneImage = Bitmap.createBitmap(imageWidth, imageHeight, conf) for (x in imageArray[0].indices) { for (y in imageArray[0][0].indices) { val grayValue = (imageArray[0][x][y][0] * 255f).toInt() val color = Color.argb( grayValue, // Alpha通道和灰度值保持一致 grayValue, grayValue, grayValue ) grayToneImage.setPixel(y, x, color) } } return grayToneImage }
第二步:优化裁剪函数
删除冗余的重复绘制代码,增加尺寸校验避免异常:
private fun cropBitmapWithMask(original: Bitmap, mask: Bitmap): Bitmap? { if (original == null || mask == null || mask.width <= 0 || mask.height <= 0) { return null } // 校验原图和掩码尺寸一致,尺寸不匹配时可先把原图缩放为掩码尺寸再处理 if (original.width != mask.width || original.height != mask.height) { return null } val cropped = Bitmap.createBitmap(mask.width, mask.height, Bitmap.Config.ARGB_8888) val canvas = Canvas(cropped) val paint = Paint(Paint.ANTI_ALIAS_FLAG) canvas.drawBitmap(original, 0.0f, 0.0f, null) paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_IN) canvas.drawBitmap(mask, 0.0f, 0.0f, paint) paint.xfermode = null return cropped }
修改完成后即可实现仅保留掩码对应区域的裁剪效果。
内容的提问来源于stack exchange,提问作者Brittle Pings
相关产品推荐
相关产品推荐

