| /* | |
| * 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; | |
| } | |
| } |