CaptureModuleUtil.java revision f2627903d11faf47c5052884bc2b23e27b8d5f94
1/*
2 * Copyright (C) 2014 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
17package com.android.camera;
18
19import android.content.Context;
20import android.content.res.Configuration;
21import android.view.Surface;
22
23import com.android.camera.debug.Log;
24import com.android.camera.debug.Log.Tag;
25import com.android.camera.util.CameraUtil;
26import com.android.camera.util.Size;
27
28import java.util.ArrayList;
29
30/**
31 * Common utility methods used in capture modules.
32 */
33public class CaptureModuleUtil {
34    private static final Tag TAG = new Tag("CaptureModuleUtil");
35
36    public static int getDeviceNaturalOrientation(Context context) {
37        Configuration config = context.getResources().getConfiguration();
38        int rotation = CameraUtil.getDisplayRotation(context);
39
40        if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
41                config.orientation == Configuration.ORIENTATION_LANDSCAPE) ||
42                ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
43                config.orientation == Configuration.ORIENTATION_PORTRAIT)) {
44            return Configuration.ORIENTATION_LANDSCAPE;
45        } else {
46            return Configuration.ORIENTATION_PORTRAIT;
47        }
48    }
49
50    /**
51     * Equivalent to the
52     * {@link CameraUtil#getOptimalPreviewSize(android.content.Context, java.util.List, double)}
53     * method for the camera1 api.
54     */
55    public static Size getOptimalPreviewSize(Context context, Size[] sizes,
56            double targetRatio) {
57        // TODO(andyhuibers): Don't hardcode this but use device's measurements.
58        final int MAX_ASPECT_HEIGHT = 1080;
59
60        // Count sizes with height <= 1080p to mimic camera1 api behavior.
61        int count = 0;
62        for (Size s : sizes) {
63            if (s.getHeight() <= MAX_ASPECT_HEIGHT) {
64                count++;
65            }
66        }
67        ArrayList<Size> camera1Sizes = new ArrayList<Size>(count);
68
69        // Set array of all sizes with height <= 1080p
70        for (Size s : sizes) {
71            if (s.getHeight() <= MAX_ASPECT_HEIGHT) {
72                camera1Sizes.add(new Size(s.getWidth(), s.getHeight()));
73            }
74        }
75
76        int optimalIndex = CameraUtil
77                .getOptimalPreviewSizeIndex(context, camera1Sizes, targetRatio);
78
79        if (optimalIndex == -1) {
80            return null;
81        }
82
83        Size optimal = camera1Sizes.get(optimalIndex);
84        for (Size s : sizes) {
85            if (s.getWidth() == optimal.getWidth() && s.getHeight() == optimal.getHeight()) {
86                return s;
87            }
88        }
89        return null;
90    }
91
92    /**
93     * Selects the preview buffer dimensions that are closest in size to the
94     * size of the view containing the preview.
95     */
96    public static Size pickBufferDimensions(Size[] supportedPreviewSizes,
97            double bestPreviewAspectRatio,
98            Context context) {
99        // Swap dimensions if the device is not in its natural orientation.
100        boolean swapDimens = (CameraUtil.getDisplayRotation(context) % 180) == 90;
101        // Swap dimensions if the device's natural orientation doesn't match
102        // the sensor orientation.
103        if (CaptureModuleUtil.getDeviceNaturalOrientation(context)
104                == Configuration.ORIENTATION_PORTRAIT) {
105            swapDimens = !swapDimens;
106        }
107        double bestAspect = bestPreviewAspectRatio;
108        if (swapDimens) {
109            bestAspect = 1 / bestAspect;
110        }
111
112        Size pick = CaptureModuleUtil.getOptimalPreviewSize(context, supportedPreviewSizes,
113                bestPreviewAspectRatio);
114        Log.d(TAG, "Picked buffer size: " + pick.toString());
115        return pick;
116    }
117}
118