Skip to content

Most visited

Recently visited

navigation
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 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.

Take a one-minute survey?
Help us improve Android tools and documentation.