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

如何通过ML Kit Selfie Segmentation在流式模式下添加图片虚拟背景?

ML Kit自拍分割流式模式下替换背景为图片的实现方案

核心思路

自拍分割会生成前景遮罩(人像区域),我们只需通过画布混合模式,将背景图作为底层,再把原图的人像区域叠加到背景图上,即可实现图片背景替换,替代原有的纯色背景。

具体实现步骤

结合你参考的官方示例代码,只需修改SelfieSegmentationProcessor类中的渲染逻辑即可:

  1. 准备并缓存背景图
    提前加载背景图,并根据相机预览尺寸缩放(避免每帧重复缩放消耗性能):

    // 在Activity或Processor类中初始化背景图
    private Bitmap backgroundBitmap;
    
    // 示例:从资源加载背景图
    backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.your_bg_image);
    // 提前缩放至相机预览尺寸(假设previewSize为相机预览的宽高)
    backgroundBitmap = Bitmap.createScaledBitmap(backgroundBitmap, previewSize.getWidth(), previewSize.getHeight(), true);
    
  2. 修改渲染逻辑,替换纯色背景为图片
    替换原有的drawColor纯色绘制逻辑,改为先画背景图,再通过混合模式叠加人像区域:

    private void draw(Canvas canvas) {
        if (isFaceDetectionEnabled && faceBoundingBox != null) {
            drawFaceBoundingBox(canvas);
        }
    
        if (backgroundBitmap == null) {
            // 背景图未加载时,回退到原粉色背景
            canvas.drawColor(Color.MAGENTA);
            canvas.drawBitmap(foregroundBitmap, 0, 0, paint);
            return;
        }
    
        // 1. 绘制缩放后的背景图
        canvas.drawBitmap(backgroundBitmap, 0, 0, null);
    
        // 2. 设置混合模式:仅显示遮罩内的人像区域
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(foregroundBitmap, 0, 0, paint);
    
        // 3. 重置混合模式,避免影响后续绘制
        paint.setXfermode(null);
    }
    
  3. 处理方向适配
    如果相机预览方向与屏幕方向不一致,需要将背景图旋转对应角度,保证背景与预览帧方向匹配:

    // 示例:旋转背景图至相机预览方向(比如90度)
    Matrix matrix = new Matrix();
    matrix.postRotate(90); // 根据实际预览角度调整
    backgroundBitmap = Bitmap.createBitmap(backgroundBitmap, 0, 0, backgroundBitmap.getWidth(), backgroundBitmap.getHeight(), matrix, true);
    

性能优化注意事项

  • 背景图提前缩放并缓存,不要在每帧渲染时重复执行缩放操作,避免流式模式下卡顿。
  • 若背景图较大,建议在子线程完成缩放、旋转等预处理操作,避免阻塞主线程。
  • 页面销毁时回收Bitmap资源,避免内存泄漏:
    @Override
     protected void onDestroy() {
         super.onDestroy();
         if (backgroundBitmap != null && !backgroundBitmap.isRecycled()) {
             backgroundBitmap.recycle();
             backgroundBitmap = null;
         }
     }
    

内容的提问来源于stack exchange,提问作者Ivan Šimović

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:40:30