zoukankan      html  css  js  c++  java
  • Android调用Camera API 拍照

    注意,Camera API在API>=21已经被废弃了,建议使用android.hardware.camera2 API来进行操作。

    调用Camera API拍照的流程如下:

    To take pictures with this class, use the following steps:

    1. Obtain an instance of Camera from open(int).
    2. Get existing (default) settings with getParameters().
    3. If necessary, modify the returned Camera.Parameters object and call setParameters(Camera.Parameters).
    4. If desired, call setDisplayOrientation(int).
    5. Important: Pass a fully initialized SurfaceHolder to setPreviewDisplay(SurfaceHolder). Without a surface, the camera will be unable to start the preview.
    6. Important: Call startPreview() to start updating the preview surface. Preview must be started before you can take a picture.
    7. When you want, call takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback) to capture a photo. Wait for the callbacks to provide the actual image data.
    8. After taking a picture, preview display will have stopped. To take more photos, call startPreview() again first.
    9. Call stopPreview() to stop updating the preview surface.
    10. Important: Call release() to release the camera for use by other applications. Applications should release the camera immediately in onPause() (and re-open() it in onResume()).

    1、声明所需权限

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    2、通过Camera.open()获取Camera实例,对于多个摄像头,那么需要遍历getNumberOfCameras(),获取每一个CameraInfo来判断是前置摄像头还是后置摄像头。

    int cameraId = 0 ;
    int numberOfCameras = Camera.getNumberOfCameras();
    CameraInfo cameraInfo = new CameraInfo();
    for (int i = 0; i < numberOfCameras; i++) {
      Camera.getCameraInfo(i, cameraInfo);
      if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
        cameraId  = i ;
        break ;
       }
     } 

     3、Camera.Parameters类是对Camera的设置操作,包括闪光灯、自动对焦,场景,白平衡等,有需要可以设置。

    PS:闪光灯就是setFlashMode(Camera.Parameters.FLASH_MODE_TORCH)来实现的

    4、设置Camera的方向,官方提供的算法如下:

    public static void setCameraDisplayOrientation(Activity activity,
             int cameraId, android.hardware.Camera camera) {
         android.hardware.Camera.CameraInfo info =
                 new android.hardware.Camera.CameraInfo();
         android.hardware.Camera.getCameraInfo(cameraId, info);
         int rotation = activity.getWindowManager().getDefaultDisplay()
                 .getRotation();
         int degrees = 0;
         switch (rotation) {
             case Surface.ROTATION_0: degrees = 0; break;
             case Surface.ROTATION_90: degrees = 90; break;
             case Surface.ROTATION_180: degrees = 180; break;
             case Surface.ROTATION_270: degrees = 270; break;
         }
    
         int result;
         if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
             result = (info.orientation + degrees) % 360;
             result = (360 - result) % 360;  // compensate the mirror
         } else {  // back-facing
             result = (info.orientation - degrees + 360) % 360;
         }
         camera.setDisplayOrientation(result);
     }

    5、设置预览视图(SurfaceHolder),一般在xml里面自定义SurfaceView,然后在Activity或者Fragment里面初始化

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                     Bundle savedInstanceState) {
      View rootView = inflater.inflate(R.layout.fragment_photo, container, false);
      SurfaceView surfaceView = (SurfaceView) rootView.findViewById(R.id.surface);
      surfaceView.getHolder().addCallback(this);
      //此方法在API<11的手机上必须调用,否则没有效果   surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
      return rootView; }

    6、启动预览和Camera声明周期管理

          @Override
          public void surfaceCreated(SurfaceHolder holder) {
                mCamera = Camera.open();
                try {
                    mCamera.setPreviewDisplay(holder);
                } catch (Exception e) {
                    e.printStackTrace();
                    return ;
                }
                setCameraDisplayOrientation(getActivity(), Camera.getNumberOfCameras()-1,mCamera);
                mCamera.startPreview();
            }
    
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
            }
    
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                mCamera.stopPreview();
                mCamera.release();
            }

    7、拍照直接调用Camera.takePicture()即可。

  • 相关阅读:
    侯策《前端开发核心知识进阶》读书笔记——JS基础
    侯策《前端开发核心知识进阶》读书笔记——API实现
    侯策《前端开发核心知识进阶》读书笔记——Javascript中的Closure
    侯策《前端开发核心知识进阶》读书笔记——Javascript中的this
    xss攻击和csrf攻击的定义及区别
    浏览器缓存类型
    函数截流和防抖
    阮一峰《ECMAScript 6 入门》读书笔记—— Generator 函数
    阮一峰《ECMAScript 6 入门》读书笔记—— Iterator
    阮一峰《ECMAScript 6 入门》读书笔记——Promise
  • 原文地址:https://www.cnblogs.com/alexthecoder/p/4363516.html
Copyright © 2011-2022 走看看