Skip to content

Most visited

Recently visited

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

Hooray!

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.