| /* |
| * Copyright 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.example.android.basicpermissions.camera; |
| |
| import android.content.Context; |
| import android.hardware.Camera; |
| import android.util.Log; |
| import android.view.Surface; |
| import android.view.SurfaceHolder; |
| import android.view.SurfaceView; |
| |
| import java.io.IOException; |
| |
| /** |
| * Camera preview that displays a {@link Camera}. |
| * |
| * Handles basic lifecycle methods to display and stop the preview. |
| * <p> |
| * Implementation is based directly on the documentation at |
| * http://developer.android.com/guide/topics/media/camera.html |
| */ |
| public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { |
| |
| private static final String TAG = "CameraPreview"; |
| private SurfaceHolder mHolder; |
| private Camera mCamera; |
| private Camera.CameraInfo mCameraInfo; |
| private int mDisplayOrientation; |
| |
| public CameraPreview(Context context, Camera camera, Camera.CameraInfo cameraInfo, |
| int displayOrientation) { |
| super(context); |
| |
| // Do not initialise if no camera has been set |
| if (camera == null || cameraInfo == null) { |
| return; |
| } |
| mCamera = camera; |
| mCameraInfo = cameraInfo; |
| mDisplayOrientation = displayOrientation; |
| |
| // Install a SurfaceHolder.Callback so we get notified when the |
| // underlying surface is created and destroyed. |
| mHolder = getHolder(); |
| mHolder.addCallback(this); |
| } |
| |
| public void surfaceCreated(SurfaceHolder holder) { |
| // The Surface has been created, now tell the camera where to draw the preview. |
| try { |
| mCamera.setPreviewDisplay(holder); |
| mCamera.startPreview(); |
| Log.d(TAG, "Camera preview started."); |
| } catch (IOException e) { |
| Log.d(TAG, "Error setting camera preview: " + e.getMessage()); |
| } |
| } |
| |
| public void surfaceDestroyed(SurfaceHolder holder) { |
| // empty. Take care of releasing the Camera preview in your activity. |
| } |
| |
| public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { |
| // 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 |
| Log.d(TAG, "Preview surface does not exist"); |
| return; |
| } |
| |
| // stop preview before making changes |
| try { |
| mCamera.stopPreview(); |
| Log.d(TAG, "Preview stopped."); |
| } catch (Exception e) { |
| // ignore: tried to stop a non-existent preview |
| Log.d(TAG, "Error starting camera preview: " + e.getMessage()); |
| } |
| |
| int orientation = calculatePreviewOrientation(mCameraInfo, mDisplayOrientation); |
| mCamera.setDisplayOrientation(orientation); |
| |
| try { |
| mCamera.setPreviewDisplay(mHolder); |
| mCamera.startPreview(); |
| Log.d(TAG, "Camera preview started."); |
| } catch (Exception e) { |
| Log.d(TAG, "Error starting camera preview: " + e.getMessage()); |
| } |
| } |
| |
| /** |
| * Calculate the correct orientation for a {@link Camera} preview that is displayed on screen. |
| * |
| * Implementation is based on the sample code provided in |
| * {@link Camera#setDisplayOrientation(int)}. |
| */ |
| public static int calculatePreviewOrientation(Camera.CameraInfo info, int rotation) { |
| 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; |
| } |
| |
| return result; |
| } |
| } |