1.Android 自定义拍照(支持前后摄像头切换)

1.布局




    
    

2.实现代码

public class MainActivity extends Activity implements View.OnClickListener,
    SurfaceHolder.Callback {

        private static final String TAG = MainActivity.class.getSimpleName();
        private static final int MEDIA_TYPE_IMAGE = 1;
        private Button switchCameraBtn, captureBtn;
        private SurfaceView surfaceSv;
        private SurfaceHolder mHolder;
        private Camera mCamera;
        // 0表示后置,1表示前置
        private int cameraPosition = 1;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.activity_main);
            findById();
            initData();
        }

        /**
         * 初始化view
         */
        private void findById() {
            switchCameraBtn = this.findViewById(R.id.id_switch_camera_btn);
            captureBtn = this.findViewById(R.id.id_capture_btn);
            surfaceSv = this.findViewById(R.id.id_area_sv);
            switchCameraBtn.setOnClickListener(this);
            captureBtn.setOnClickListener(this);
        }

        /**
         * 初始化相关data
         */
        private void initData() {
            // 获得句柄
            mHolder = surfaceSv.getHolder();
            // 添加回调
            mHolder.addCallback(this);
        }

        @Override
        public void onStart() {
            super.onStart();
            if (this.checkCameraHardware(this) && (mCamera == null)) {
                // 打开camera
                mCamera = getCamera();
                if (mHolder != null) {
                    setStartPreview(mCamera,mHolder);
                }
            }
        }

        private Camera getCamera() {
            Camera camera = null;
            try {
                camera = Camera.open();
            } catch (Exception e) {
// Camera is not available (in use or does not exist)
                camera = null;
                Log.e(TAG, "Camera is not available (in use or does not exist)");
            }
            return camera;
        }
        @Override
        public void onPause() {
            super.onPause();
/**
 * 记得释放camera,方便其他应用调用
 */
            releaseCamera();
        }
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
/**
 * 释放mCamera
 */
        private void releaseCamera() {
            if (mCamera != null) {
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();// 停掉原来摄像头的预览
                mCamera.release();
                mCamera = null;
            }
        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.id_switch_camera_btn:
                    // 切换前后摄像头
                    int cameraCount = 0;
                    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
                    cameraCount = Camera.getNumberOfCameras();// 得到摄像头的个数

                    for (int i = 0; i < cameraCount; i++) {
                        Camera.getCameraInfo(i, cameraInfo);// 得到每一个摄像头的信息
                        if (cameraPosition == 1) {
                            // 现在是后置,变更为前置
                            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                            /**
                             * 记得释放camera,方便其他应用调用
                             */
                                releaseCamera();
                                // 打开当前选中的摄像头
                                mCamera = Camera.open(i);
                                // 通过surfaceview显示取景画面
                                setStartPreview(mCamera,mHolder);
                                cameraPosition = 0;
                                break;
                            }
                        } else {
                            // 现在是前置, 变更为后置
                            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                                /**
                                 * 记得释放camera,方便其他应用调用
                                 */
                                releaseCamera();
                                mCamera = Camera.open(i);
                                setStartPreview(mCamera,mHolder);
                                cameraPosition = 1;
                                break;
                            }
                        }
                    }
                    break;
                case R.id.id_capture_btn:
                    mCamera.takePicture(null, null, picture);
                    break;
            }
        }
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            setStartPreview(mCamera,mHolder);
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
            // If your preview can change or rotate, take care of those events here.
            // Make sure to stop the preview before resizing or reformatting it.

            if (mHolder.getSurface() == null) {
                // preview surface does not exist
                return;
            }
            // stop preview before making changes
            try {
                mCamera.stopPreview();
            } catch (Exception e) {
                // ignore: tried to stop a non-existent preview
            }
            // set preview size and make any resize, rotate or
            // reformatting changes here
            // start preview with new settings
            setStartPreview(mCamera,mHolder);
        }
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // 当surfaceview关闭时,关闭预览并释放资源
            /**
             * 记得释放camera,方便其他应用调用
             */
            releaseCamera();
            holder = null;
            surfaceSv = null;
        }
        /**
         * 创建png图片回调数据对象
         */
        Camera.PictureCallback picture = new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                Toast.makeText(MainActivity.this,"拍照",Toast.LENGTH_SHORT).show();
                camera.startPreview();//拍完照  重新打开预览
            }
        };


        /** Check if this device has a camera */
        private boolean checkCameraHardware(Context context) {
            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_CAMERA)) {
                // this device has a camera
                return true;
            } else {
                // no camera on this device
                return false;
            }
        }

        /**
         * 设置camera显示取景画面,并预览
         * @param camera
         */
        private void setStartPreview(Camera camera,SurfaceHolder holder){
            try {
                Camera.Parameters parameters = mCamera.getParameters();
                setDispaly(parameters, mCamera);
                camera.setPreviewDisplay(holder);
                camera.startPreview();
            } catch (IOException e) {
                Log.d(TAG, "Error starting camera preview: " + e.getMessage());
            }
        }

        // 控制图像的正确显示方向
        private void setDispaly(Camera.Parameters parameters, Camera camera) {
            if (Integer.parseInt(Build.VERSION.SDK) >= 8) {
                setDisplayOrientation(camera, 90);
            } else {
                parameters.setRotation(90);
            }
        }

        // 实现的图像的正确显示
        private void setDisplayOrientation(Camera camera, int i) {
            Method downPolymorphic;
            try {
                downPolymorphic = camera.getClass().getMethod(
                        "setDisplayOrientation", new Class[] { int.class });
                if (downPolymorphic != null) {
                    downPolymorphic.invoke(camera, new Object[] { i });
                }
            } catch (Exception e) {
                Log.e("Came_e", "图像出错");
            }
        }
    }

你可能感兴趣的:(1.Android 自定义拍照(支持前后摄像头切换))