BasicRenderScript / src / com.example.android.common.media /

CameraHelper.java

1
/*
2
 * Copyright (C) 2013 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.common.media;
18
 
19
import android.annotation.TargetApi;
20
import android.hardware.Camera;
21
import android.os.Build;
22
import android.os.Environment;
23
import android.util.Log;
24
 
25
import java.io.File;
26
import java.text.SimpleDateFormat;
27
import java.util.Date;
28
import java.util.List;
29
 
30
/**
31
 * Camera related utilities.
32
 */
33
public class CameraHelper {
34
 
35
    public static final int MEDIA_TYPE_IMAGE = 1;
36
    public static final int MEDIA_TYPE_VIDEO = 2;
37
 
38
    /**
39
     * Iterate over supported camera preview sizes to see which one best fits the
40
     * dimensions of the given view while maintaining the aspect ratio. If none can,
41
     * be lenient with the aspect ratio.
42
     *
43
     * @param sizes Supported camera preview sizes.
44
     * @param w The width of the view.
45
     * @param h The height of the view.
46
     * @return Best match camera preview size to fit in the view.
47
     */
48
    public static  Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
49
        // Use a very small tolerance because we want an exact match.
50
        final double ASPECT_TOLERANCE = 0.1;
51
        double targetRatio = (double) w / h;
52
        if (sizes == null)
53
            return null;
54
 
55
        Camera.Size optimalSize = null;
56
 
57
        // Start with max value and refine as we iterate over available preview sizes. This is the
58
        // minimum difference between view and camera height.
59
        double minDiff = Double.MAX_VALUE;
60
 
61
        // Target view height
62
        int targetHeight = h;
63
 
64
        // Try to find a preview size that matches aspect ratio and the target view size.
65
        // Iterate over all available sizes and pick the largest size that can fit in the view and
66
        // still maintain the aspect ratio.
67
        for (Camera.Size size : sizes) {
68
            double ratio = (double) size.width / size.height;
69
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
70
                continue;
71
            if (Math.abs(size.height - targetHeight) < minDiff) {
72
                optimalSize = size;
73
                minDiff = Math.abs(size.height - targetHeight);
74
            }
75
        }
76
 
77
        // Cannot find preview size that matches the aspect ratio, ignore the requirement
78
        if (optimalSize == null) {
79
            minDiff = Double.MAX_VALUE;
80
            for (Camera.Size size : sizes) {
81
                if (Math.abs(size.height - targetHeight) < minDiff) {
82
                    optimalSize = size;
83
                    minDiff = Math.abs(size.height - targetHeight);
84
                }
85
            }
86
        }
87
        return optimalSize;
88
    }
89
 
90
    /**
91
     * @return the default camera on the device. Return null if there is no camera on the device.
92
     */
93
    public static Camera getDefaultCameraInstance() {
94
        return Camera.open();
95
    }
96
 
97
 
98
    /**
99
     * @return the default rear/back facing camera on the device. Returns null if camera is not
100
     * available.
101
     */
102
    public static Camera getDefaultBackFacingCameraInstance() {
103
        return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
104
    }
105
 
106
    /**
107
     * @return the default front facing camera on the device. Returns null if camera is not
108
     * available.
109
     */
110
    public static Camera getDefaultFrontFacingCameraInstance() {
111
        return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
112
    }
113
 
114
 
115
    /**
116
     *
117
     * @param position Physical position of the camera i.e Camera.CameraInfo.CAMERA_FACING_FRONT
118
     *                 or Camera.CameraInfo.CAMERA_FACING_BACK.
119
     * @return the default camera on the device. Returns null if camera is not available.
120
     */
121
    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
122
    private static Camera getDefaultCamera(int position) {
123
        // Find the total number of cameras available
124
        int  mNumberOfCameras = Camera.getNumberOfCameras();
125
 
126
        // Find the ID of the back-facing ("default") camera
127
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
128
        for (int i = 0; i < mNumberOfCameras; i++) {
129
            Camera.getCameraInfo(i, cameraInfo);
130
            if (cameraInfo.facing == position) {
131
                return Camera.open(i);
132
 
133
            }
134
        }
135
 
136
        return null;
137
    }
138
 
139
    /**
140
     * Creates a media file in the {@code Environment.DIRECTORY_PICTURES} directory. The directory
141
     * is persistent and available to other applications like gallery.
142
     *
143
     * @param type Media type. Can be video or image.
144
     * @return A file object pointing to the newly created file.
145
     */
146
    public  static File getOutputMediaFile(int type){
147
        // To be safe, you should check that the SDCard is mounted
148
        // using Environment.getExternalStorageState() before doing this.
149
        if (!Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
150
            return  null;
151
        }
152
 
153
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
154
                Environment.DIRECTORY_PICTURES), "CameraSample");
155
        // This location works best if you want the created images to be shared
156
        // between applications and persist after your app has been uninstalled.
157
 
158
        // Create the storage directory if it does not exist
159
        if (! mediaStorageDir.exists()){
160
            if (! mediaStorageDir.mkdirs()) {
161
                Log.d("CameraSample", "failed to create directory");
162
                return null;
163
            }
164
        }
165
 
166
        // Create a media file name
167
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
168
        File mediaFile;
169
        if (type == MEDIA_TYPE_IMAGE){
170
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
171
                    "IMG_"+ timeStamp + ".jpg");
172
        } else if(type == MEDIA_TYPE_VIDEO) {
173
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
174
                    "VID_"+ timeStamp + ".mp4");
175
        } else {
176
            return null;
177
        }
178
 
179
        return mediaFile;
180
    }
181
 
182
}