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()即可。

原文地址:https://www.cnblogs.com/alexthecoder/p/4363516.html