android 自定义相机,Camera,相机遮罩层

实现效果:

    

实现方法:一个自定义view实现demo

一、自定义相机Camera,无API版本限制

(1)。实现接口 implements SurfaceHolder.Callback

private SurfaceView mView;

private Camera mCamera;
private int cameraId = 0;//前置1、后置0

初期化Camera

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                if (cameraId == 0) cameraId = i;
            }
        }

        mCamera = Camera.open(cameraId);
        mCamera.setDisplayOrientation(90);
        Camera.getCameraInfo(cameraId, cameraInfo);
        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
//            mFaceView.setFront(true);
        }
        Log.i(TAG, "surfaceCreated");
        try {
            mCamera.setPreviewDisplay(mView.getHolder());
        } catch (Exception e) {
            Log.e(TAG, "Could not preview the image.", e);
        }
    }

(2)、布局layout.xml添加SurfaceView预览相机

<SurfaceView
    android:id="@+id/surfaceview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"/>
mView = (SurfaceView) findViewById(R.id.surfaceview);
mCamera.setPreviewDisplay(mView.getHolder());

(3)、启动相机Camera类

private void startPreview() {
    if (mCamera != null) {
        Log.i(TAG, "startPreview0000");
        mCamera.startPreview();
        mCamera.setPreviewCallback(this);
    }
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Check for the camera permission before accessing the camera.  If the
    // permission is not granted yet, request permission.
    SurfaceHolder holder = mView.getHolder();
    holder.addCallback(this);
    holder.setFormat(ImageFormat.NV21);
    Log.i("lgq", "......onPostCreate");
}

(4)、点击拍照获取照片

创建回Camera调接口

    private Camera.PictureCallback mPicture = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            // 获取Jpeg图片,并保存在sd卡上
//            buff = data;
            bitmap = Bytes2Bimap(data);

            mHandler.sendEmptyMessageDelayed(REFRESH_COMPLETE, 0);
            
        }
    };

点击拍照

imageView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mCamera.autoFocus(new Camera.AutoFocusCallback() {

            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                // 从Camera捕获图片
                mCamera.takePicture(null, null, mPicture);
            }
        });
    }
});

二、.camera2.CameraDevice,TextureView实现自定义拍照。API=21以下的手机不可用,

(1)、layout.xml文件添加TextureView

<TextureView
    android:id="@+id/tv_textview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

实现代码比较长篇。。。。。。。。

demo链接:https://download.csdn.net/download/meixi_android/11168640

1、创建自定义遮罩层view

/**
 * 人脸检测区域View
 */
public class FaceDetectRoundView extends View {

    private static final String TAG = FaceDetectRoundView.class.getSimpleName();

    public static final float SURFACE_HEIGHT = 1000f;
    public static final float SURFACE_RATIO = 0.75f;
    public static final float WIDTH_SPACE_RATIO = 0.33f;
    public static final float HEIGHT_RATIO = 0.1f;
    public static final float HEIGHT_EXT_RATIO = 0.2f;
    public static final int CIRCLE_SPACE = 5;
    public static final int PATH_SPACE = 16;
    public static final int PATH_SMALL_SPACE = 12;
    public static final int PATH_WIDTH = 4;

    public static final int COLOR_BG = Color.parseColor("#2F2F33");
    public static final int COLOR_RECT = Color.parseColor("#FFFFFF");
    public static final int COLOR_ROUND = Color.parseColor("#FFA800");

    private PathEffect mFaceRoundPathEffect = null;
    // new DashPathEffect(new float[]{PATH_SPACE, PATH_SPACE}, 1);
    private Paint mBGPaint;
    private Paint mPathPaint;
    private Paint mFaceRectPaint;
    private Paint mFaceRoundPaint;
    private Rect mFaceRect;
    private Rect mFaceDetectRect;

    private float mX;
    private float mY;
    private float mR;
    private boolean mIsDrawDash = true;

    public FaceDetectRoundView(Context context) {
        this(context, null);

    }

    public FaceDetectRoundView(Context context, AttributeSet attrs) {
        super(context, attrs);

        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        float pathSpace = dip2px(context, PATH_SPACE);
        float pathSmallSpace = dip2px(context, PATH_SMALL_SPACE);
        float pathWidth = dip2px(context, PATH_WIDTH);
        mFaceRoundPathEffect = new DashPathEffect(
                new float[]{pathSpace, dm.heightPixels < SURFACE_HEIGHT
                        ? pathSmallSpace : pathSpace}, 1);

        mBGPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBGPaint.setColor(COLOR_BG);
        mBGPaint.setStyle(Paint.Style.FILL);
        mBGPaint.setAntiAlias(true);
        mBGPaint.setDither(true);

        mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPathPaint.setColor(COLOR_ROUND);
        mPathPaint.setStrokeWidth(pathWidth);
        mPathPaint.setStyle(Paint.Style.STROKE);
        mPathPaint.setAntiAlias(true);
        mPathPaint.setDither(true);

        mFaceRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mFaceRectPaint.setColor(COLOR_RECT);
        mFaceRectPaint.setStrokeWidth(pathWidth);
        mFaceRectPaint.setStyle(Paint.Style.STROKE);
        mFaceRectPaint.setAntiAlias(true);
        mFaceRectPaint.setDither(true);

        mFaceRoundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mFaceRoundPaint.setColor(COLOR_ROUND);
        mFaceRoundPaint.setStyle(Paint.Style.FILL);
        mFaceRoundPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        mFaceRoundPaint.setAntiAlias(true);
        mFaceRoundPaint.setDither(true);
    }

、、、、、、、、、、、、、

、、、、、、、

、、、、

2、添加自定义view方法

在activity中添加自定义遮罩层view即可实现

private FaceDetectRoundView mFaceView;
mFaceView = new FaceDetectRoundView(this);
mFaceView.setAlpha(0.43f);
addContentView(mFaceView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

demo云盘:https://pan.baidu.com/s/1n5zcprwVGUlLjLvVm0qjrw

在线bug交流:QQ1085220040

发布了339 篇原创文章 · 获赞 66 · 访问量 36万+

猜你喜欢

转载自blog.csdn.net/meixi_android/article/details/89924511