如何对图像特定区域遮罩,生成黑底白遮罩区域的图像并保存
实现ImageView中目标对象的黑白遮罩生成与保存
针对你需要为ImageView里的狗生成「目标区域白色、其余区域黑色」的遮罩并保存为Bitmap/JPG/PNG的需求,这里提供两种可行方案:
方案一:手动绘制遮罩(适合固定简单场景)
如果狗的位置和轮廓固定,可以直接通过Canvas手动绘制遮罩:
- 从ImageView提取原始Bitmap
ImageView targetIv = findViewById(R.id.your_image_view_id); Bitmap originalBmp = ((BitmapDrawable) targetIv.getDrawable()).getBitmap();
- 创建全黑的空白遮罩Bitmap
int width = originalBmp.getWidth(); int height = originalBmp.getHeight(); Bitmap maskBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(maskBmp); // 先绘制全黑背景 Paint blackPaint = new Paint(); blackPaint.setColor(Color.BLACK); canvas.drawRect(0, 0, width, height, blackPaint);
- 绘制白色遮罩区域
根据狗的实际轮廓,选择矩形或路径绘制:
Paint whitePaint = new Paint(); whitePaint.setColor(Color.WHITE); // 示例1:如果是矩形区域,替换为实际坐标 canvas.drawRect(100, 80, 500, 700, whitePaint); // 示例2:不规则轮廓用Path绘制 // Path dogPath = new Path(); // dogPath.moveTo(120, 90); // dogPath.lineTo(520, 110); // ... 依次连接轮廓点 // canvas.drawPath(dogPath, whitePaint);
- 保存遮罩文件
// 保存为PNG(无压缩损失,推荐) try (FileOutputStream out = new FileOutputStream(new File(getExternalFilesDir(null), "dog_mask.png"))) { maskBmp.compress(Bitmap.CompressFormat.PNG, 100, out); } catch (IOException e) { e.printStackTrace(); } // 保存为JPG try (FileOutputStream out = new FileOutputStream(new File(getExternalFilesDir(null), "dog_mask.jpg"))) { maskBmp.compress(Bitmap.CompressFormat.JPEG, 90, out); } catch (IOException e) { e.printStackTrace(); }
方案二:自动图像分割(精准识别动态场景)
如果需要自动识别狗的区域,推荐使用ML Kit图像分割或TensorFlow Lite模型,以ML Kit为例:
- 添加依赖
在app模块的build.gradle中加入:
dependencies { implementation 'com.google.mlkit:image-segmentation:16.0.0' implementation 'com.google.mlkit:image-segmentation-custom:16.0.0' // 可选自定义模型 }
- 执行分割并生成遮罩
// 初始化图像分割器 ImageSegmenterOptions options = new ImageSegmenterOptions.Builder() .setDetectorMode(ImageSegmenterOptions.SINGLE_IMAGE_MODE) .build(); ImageSegmenter segmenter = ImageSegmenter.getClient(options); // 转换原始Bitmap为InputImage InputImage inputImage = InputImage.fromBitmap(originalBmp, 0); // 异步处理图像 segmenter.process(inputImage) .addOnSuccessListener(result -> { Mask mask = result.getMask(); ByteBuffer buffer = mask.getBuffer(); buffer.rewind(); Bitmap maskBmp = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888); // 遍历每个像素,置信度>0.5的区域设为白色,其余黑色 for (int y = 0; y < mask.getHeight(); y++) { for (int x = 0; x < mask.getWidth(); x++) { float confidence = buffer.getFloat(); maskBmp.setPixel(x, y, confidence > 0.5f ? Color.WHITE : Color.BLACK); } } // 保存遮罩(同方案一的保存代码) }) .addOnFailureListener(e -> e.printStackTrace());
注意事项
- 手动绘制适合固定场景,需要精准的轮廓坐标;自动分割适合动态场景,准确率更高
- PNG格式保存遮罩无颜色损失,是首选;JPG会有压缩,可能导致边缘模糊
- Android 10及以上需要使用Scoped Storage处理文件保存,避免权限问题
内容的提问来源于stack exchange,提问作者George Glyn
相关产品推荐
相关产品推荐

