美文网首页安卓
[Android] 相机镜头前添加人脸提示框

[Android] 相机镜头前添加人脸提示框

作者: 闭门造折 | 来源:发表于2019-06-06 13:26 被阅读0次

    需求

    我们之前做了一款拍照APP,现在需要在拍摄的时候,提供一个人脸提示框(因为我们最后不是保留所有的图像,而是仅保留中间一部分图像)

    思路

    在预览图层前,再添加一层画布,在新的画布上绘制人脸框和矩形框。也就是说,实际上我们仅仅是在预览的镜头前添加,而非对相机做什么修改。

    具体步骤

    步骤一:添加新图层

    使用FrameLayout(下方的内容会覆盖在上方的内容上),在我们的预览用SurfaceView之上添加一个自定义画布

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
    
        <SurfaceView
            android:id="@+id/cameraSV"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:visibility="visible" />
        
        <com.example.matting.SVDraw
             android:id="@+id/drawIV"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent" />
    </FrameLayout>
    

    步骤二:自定义画布设置

    public class SVDraw extends SurfaceView implements Callback{
        protected SurfaceHolder sh;
        private String TestTag = "TestLog";
        
        public SVDraw(Context context, AttributeSet attrs) {
            super(context, attrs);
            
            sh = getHolder();
            sh.addCallback(this);
            sh.setFormat(PixelFormat.TRANSPARENT); // 设置透明
            setZOrderOnTop(true); // 置顶
        }
    
        /*
        ...其他的一些函数
        */
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // TODO Auto-generated method stub
            
        }
    }
    

    步骤三:在画布上绘制矩形框及人脸框

    使用函数的形式,方便外部调用

    public synchronized void drawRect() {
        Canvas canvas = sh.lockCanvas();
        canvas.drawColor(Color.TRANSPARENT);
    
        // 红色提示矩形框画笔设置
        Paint redPaint = new Paint();
        redPaint.setAntiAlias(true);
        redPaint.setColor(Color.RED);
        redPaint.setStyle(Style.STROKE);
        redPaint.setStrokeWidth(4f);
        redPaint.setAlpha(100);
        
        // 绿色人物提示框画笔设置
        Paint greenPaint = new Paint();
        greenPaint.setAntiAlias(true);
        greenPaint.setColor(0xFFA4C739);
        greenPaint.setStrokeWidth(3.5f);
        greenPaint.setStyle(Paint.Style.STROKE);
    
        // 将画布原点移至画布中央(方便画布选点)
        canvas.translate(mWidth / 2, mHeight / 2 - 200);
    
        // 绘制外围红色边框
        canvas.drawRect(new Rect(-360, -480, 360, 480), redPaint);
    
        // 头部
        RectF rectf_head = new RectF(-225, -375, 225, 15);
        canvas.drawArc(rectf_head, 200, 140, false, greenPaint);
    
        // 下颌
        RectF rectf_mouse = new RectF(-165, 120, 165, 322);
        canvas.drawArc(rectf_mouse, 20, 140, false, greenPaint);
    
    
        // 衬衣
        canvas.drawLine(-141, 315, -300, 458, greenPaint);
        canvas.drawLine(141, 315, 300, 458, greenPaint);
    
        sh.unlockCanvasAndPost(canvas);
    }
    

    分为两部分,一部分红色画笔,绘制的是最终的裁剪区域外轮廓。一部分是分步的人脸绘制。也许可以采用贴图的方法整体实现,但是由于我没有半透明的矢量图可用,所以用蠢方法实现了。

    步骤四:清屏函数

    由于我们的人脸框是可以随时收回的,所以要添加一个函数,用于将绘制的图案隐藏,实际上我们是将绘制的图案直接清除,以此实现取消辅助线

    void clearDraw() {
        Canvas canvas = sh.lockCanvas();
        canvas.drawColor(Color.BLUE);
        sh.unlockCanvasAndPost(canvas);
    }
    

    步骤五:声明属性

    private SVDraw myDraw = null;
    

    步骤六:onCreate中初始化第二层屏幕

    // 初始化画板
    myDraw = (SVDraw) findViewById(R.id.drawIV);
    

    步骤七:添加函数调用

    当需要添加辅助线的时候(比如说点击了添加按钮),调用相应的函数即可

    myDraw.drawRect();
    

    效果展示

    提示框效果展示

    灰色区域是预览区域,点击绘制后会显示红色提示框和绿色人脸框

    完整代码

    完整代码请移步github项目Github项目:《Matting》 By ZaoZhe6666
    在camera.xml中是相机的相关布局。
    在SVDraw.java中是本文提到的设置画布的绘制部分。
    在UseCameraActivity中是本文对画布绘制功能(辅助线添加功能)的具体使用。

    相关文章

      网友评论

        本文标题:[Android] 相机镜头前添加人脸提示框

        本文链接:https://www.haomeiwen.com/subject/wyztnqtx.html