Android 相机遮罩CameraMask

作者: SwitchLife | 来源:发表于2018-07-17 18:20 被阅读0次

    开篇

      相机遮罩。

    • 支持修改遮罩颜色以及透明度
    • 支持修改相机镜头
    • 支持设置提示文字以及位置、字体、颜色
    • 可获取相机镜头位置Rect

    效果截屏

    立即体验

    扫描以下二维码下载体验App(从0.2.3版本开始,体验App内嵌版本更新检测功能):


    JSCKit库传送门:https://github.com/JustinRoom/JSCKit

    简析源码

    CameraMask.java

    • 初始化视图以及attribute
        public void init(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            textView = new TextView(context);
            textView.setTextColor(Color.WHITE);
            textView.setGravity(Gravity.CENTER_HORIZONTAL);
            addView(textView, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraMask, defStyleAttr, 0);
            topMargin = a.getDimensionPixelSize(R.styleable.CameraMask_cm_top_margin, 0);
            maskColor = a.getColor(R.styleable.CameraMask_cm_mask_color, 0x99000000);
    
            String text = a.getString(R.styleable.CameraMask_cm_text);
            int textColor = a.getColor(R.styleable.CameraMask_cm_text_color, Color.WHITE);
            if (a.hasValue(R.styleable.CameraMask_cm_text_background)) {
                Drawable drawable = a.getDrawable(R.styleable.CameraMask_cm_text_background);
                textView.setBackground(drawable);
            }
            if (a.hasValue(R.styleable.CameraMask_cm_text_background_color)) {
                int textBackgroundColor = a.getColor(R.styleable.CameraMask_cm_text_background_color, Color.TRANSPARENT);
                textView.setBackgroundColor(textBackgroundColor);
            }
            textLocation = a.getInt(R.styleable.CameraMask_cm_text_location, LOCATION_BELOW_CAMERA_LENS);
            textVerticalMargin = a.getDimensionPixelSize(R.styleable.CameraMask_cm_text_margin, 0);
            a.recycle();
            textView.setText(text);
            textView.setTextColor(textColor);
            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
    
            setWillNotDraw(false);
            setCameraLensBitmap(decodeDefaultCameraLens());
        }
    

    添加提示文字TextView、解析attribute属性。
    setWillNotDraw(false)ViewGroup执行自己的onDraw(Canvas canvas)方法。

    • 计算相机镜头的尺寸、放置提示文字TextView
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));
            initCameraLensSize(getMeasuredWidth());
            MarginLayoutParams params = (MarginLayoutParams) textView.getLayoutParams();
            params.leftMargin = cameraLensRect.left;
            params.rightMargin = cameraLensRect.left;
            switch (textLocation) {
                case LOCATION_BELOW_CAMERA_LENS:
                    params.topMargin = cameraLensRect.bottom + textVerticalMargin;
                    break;
                case LOCATION_ABOVE_CAMERA_LENS:
                    params.topMargin = cameraLensRect.top - textVerticalMargin;
                    break;
            }
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    
        private void initCameraLensSize(int width) {
            int cameraLensSize = width * 3 / 4;
            int left = (width - cameraLensSize) / 2;
            cameraLensRect.set(left, topMargin, left + cameraLensSize, topMargin + cameraLensSize);
        }
    

    相机镜头尺寸为父View宽度的四分之三

    • onDraw(Canvas canvas)
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            paint.setColor(maskColor);
            canvas.drawRect(0, 0, getWidth(), topMargin, paint);
            canvas.drawRect(0, cameraLensRect.bottom, getWidth(), getHeight(), paint);
            canvas.drawRect(0, topMargin, cameraLensRect.left, cameraLensRect.bottom, paint);
            canvas.drawRect(cameraLensRect.right, topMargin, getWidth(), cameraLensRect.bottom, paint);
    
            if (bitmap != null) {
                float scale = cameraLensRect.width() * 1.0f / bitmap.getWidth();
                matrix.setScale(scale, scale);
                canvas.save();
                canvas.translate(cameraLensRect.left, topMargin);
                canvas.drawBitmap(bitmap, matrix, null);
                canvas.restore();
            }
        }
    

    填充相机镜头四周。
    画相机镜头。

    使用示例

    getTextView()获取提示文字TextView。
    setTextVerticalMargin(int textVerticalMargin)设置提示文字与相机镜头的间距。
    setTextLocation(int textLocation)设置提示文字位置:LOCATION_BELOW_CAMERA_LENS——位于相机镜头下方、LOCATION_ABOVE_CAMERA_LENS——位于相机镜头上方。
    setMaskColor(int maskColor)设置遮罩ARGB颜色。
    setCameraLensBitmap(Bitmap bitmap)设置相机镜头Bitmap。
    setTopMargin(int topMargin)设置相机镜头与父View顶部的距离。
    getCameraLensRect()获取相机镜头在父View中的位置。我们可以利用这个Rect位置信息做很多事情,例如在相机预览中生成这块区域的图片(或者识别此区域的数据信息)。
    https://github.com/JustinRoom/JSCKit/blob/master/app/src/main/java/jsc/exam/jsckit/ui/component/CameraMaskActivity.java

    篇尾!

      QQ:1006368252WeChat:eoy9527

    最甜美的是爱情,最苦涩的也是爱情。 —— 菲·贝利

    相关文章

      网友评论

        本文标题:Android 相机遮罩CameraMask

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