CaptureModuleUtil.java revision e3dfd5a433e39d76578b379fe1539864cf924cee
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<com.android.ex.camera2.portability.Size> camera1Sizes =
68                new ArrayList<com.android.ex.camera2.portability.Size>(count);
69
70        // Set array of all sizes with height <= 1080p
71        for (Size s : sizes) {
72            if (s.getHeight() <= MAX_ASPECT_HEIGHT) {
73                camera1Sizes.add(
74                        new com.android.ex.camera2.portability.Size(s.getWidth(), s.getHeight()));
75            }
76        }
77
78        int optimalIndex = CameraUtil
79                .getOptimalPreviewSizeIndex(context, camera1Sizes, targetRatio);
80
81        if (optimalIndex == -1) {
82            return null;
83        }
84
85        com.android.ex.camera2.portability.Size optimal = camera1Sizes.get(optimalIndex);
86        for (Size s : sizes) {
87            if (s.getWidth() == optimal.width() && s.getHeight() == optimal.height()) {
88                return s;
89            }
90        }
91        return null;
92    }
93
94    /**
95     * Selects the preview buffer dimensions that are closest in size to the
96     * size of the view containing the preview.
97     */
98    public static Size pickBufferDimensions(Size[] supportedPreviewSizes,
99            double bestPreviewAspectRatio,
100            Context context) {
101        // Swap dimensions if the device is not in its natural orientation.
102        boolean swapDimens = (CameraUtil.getDisplayRotation(context) % 180) == 90;
103        // Swap dimensions if the device's natural orientation doesn't match
104        // the sensor orientation.
105        if (CaptureModuleUtil.getDeviceNaturalOrientation(context)
106                == Configuration.ORIENTATION_PORTRAIT) {
107            swapDimens = !swapDimens;
108        }
109        double bestAspect = bestPreviewAspectRatio;
110        if (swapDimens) {
111            bestAspect = 1 / bestAspect;
112        }
113
114        Size pick = CaptureModuleUtil.getOptimalPreviewSize(context, supportedPreviewSizes,
115                bestPreviewAspectRatio);
116        Log.d(TAG, "Picked buffer size: " + pick.toString());
117        return pick;
118    }
119}
120