Home | History | Annotate | Download | only in camera
      1 /*
      2 * Copyright 2015 The Android Open Source Project
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 *     http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 package com.example.android.basicpermissions.camera;
     18 
     19 import android.content.Context;
     20 import android.hardware.Camera;
     21 import android.util.AttributeSet;
     22 import android.util.Log;
     23 import android.view.Surface;
     24 import android.view.SurfaceHolder;
     25 import android.view.SurfaceView;
     26 
     27 import java.io.IOException;
     28 
     29 /**
     30  * Camera preview that displays a {@link Camera}.
     31  * <p>
     32  * Handles basic lifecycle methods to display and stop the preview.
     33  * <p>
     34  * Implementation is based directly on the documentation at
     35  * http://developer.android.com/guide/topics/media/camera.html
     36  */
     37 public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
     38 
     39     private static final String TAG = "CameraPreview";
     40 
     41     private SurfaceHolder mHolder;
     42     private Camera mCamera;
     43     private Camera.CameraInfo mCameraInfo;
     44     private int mDisplayOrientation;
     45 
     46     public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr) {
     47         this(context, attrs, defStyleAttr, null, null, 0);
     48     }
     49 
     50     public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr,
     51             Camera camera, Camera.CameraInfo cameraInfo, int displayOrientation) {
     52         super(context, attrs, defStyleAttr);
     53 
     54         // Do not initialise if no camera has been set
     55         if (camera == null || cameraInfo == null) {
     56             return;
     57         }
     58         mCamera = camera;
     59         mCameraInfo = cameraInfo;
     60         mDisplayOrientation = displayOrientation;
     61 
     62         // Install a SurfaceHolder.Callback so we get notified when the
     63         // underlying surface is created and destroyed.
     64         mHolder = getHolder();
     65         mHolder.addCallback(this);
     66     }
     67 
     68     /**
     69      * Calculate the correct orientation for a {@link Camera} preview that is displayed on screen.
     70      * <p>
     71      * Implementation is based on the sample code provided in
     72      * {@link Camera#setDisplayOrientation(int)}.
     73      */
     74     public static int calculatePreviewOrientation(Camera.CameraInfo info, int rotation) {
     75         int degrees = 0;
     76 
     77         switch (rotation) {
     78             case Surface.ROTATION_0:
     79                 degrees = 0;
     80                 break;
     81             case Surface.ROTATION_90:
     82                 degrees = 90;
     83                 break;
     84             case Surface.ROTATION_180:
     85                 degrees = 180;
     86                 break;
     87             case Surface.ROTATION_270:
     88                 degrees = 270;
     89                 break;
     90         }
     91 
     92         int result;
     93         if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
     94             result = (info.orientation + degrees) % 360;
     95             result = (360 - result) % 360;  // compensate the mirror
     96         } else {  // back-facing
     97             result = (info.orientation - degrees + 360) % 360;
     98         }
     99 
    100         return result;
    101     }
    102 
    103     public void surfaceCreated(SurfaceHolder holder) {
    104         // The Surface has been created, now tell the camera where to draw the preview.
    105         try {
    106             mCamera.setPreviewDisplay(holder);
    107             mCamera.startPreview();
    108             Log.d(TAG, "Camera preview started.");
    109         } catch (IOException e) {
    110             Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    111         }
    112     }
    113 
    114     public void surfaceDestroyed(SurfaceHolder holder) {
    115         // empty. Take care of releasing the Camera preview in your activity.
    116     }
    117 
    118     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    119         // If your preview can change or rotate, take care of those events here.
    120         // Make sure to stop the preview before resizing or reformatting it.
    121 
    122         if (mHolder.getSurface() == null) {
    123             // preview surface does not exist
    124             Log.d(TAG, "Preview surface does not exist");
    125             return;
    126         }
    127 
    128         // stop preview before making changes
    129         try {
    130             mCamera.stopPreview();
    131             Log.d(TAG, "Preview stopped.");
    132         } catch (Exception e) {
    133             // ignore: tried to stop a non-existent preview
    134             Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    135         }
    136 
    137         int orientation = calculatePreviewOrientation(mCameraInfo, mDisplayOrientation);
    138         mCamera.setDisplayOrientation(orientation);
    139 
    140         try {
    141             mCamera.setPreviewDisplay(mHolder);
    142             mCamera.startPreview();
    143             Log.d(TAG, "Camera preview started.");
    144         } catch (Exception e) {
    145             Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    146         }
    147     }
    148 }
    149