blob: a70dca93a4438980c205ae49480ad3bc0227751a [file] [log] [blame]
Sascha Haeberlinga5c41b82014-07-29 11:14:39 -07001/*
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;
Sascha Haeberlinga5c41b82014-07-29 11:14:39 -070021import android.view.Surface;
22
23import com.android.camera.debug.Log;
24import com.android.camera.debug.Log.Tag;
25import com.android.camera.util.CameraUtil;
Sascha Haeberlinge3dfd5a2014-08-05 15:54:42 -070026import com.android.camera.util.Size;
Sascha Haeberlinga5c41b82014-07-29 11:14:39 -070027
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) {
Sascha Haeberlingc6da1a12014-11-06 09:50:51 -080057 return getOptimalPreviewSize(context, sizes, targetRatio, null );
58 }
59
60 /**
61 * Returns the best preview size based on the current display resolution,
62 * the available preview sizes, the target aspect ratio (typically the
63 * aspect ratio of the picture to be taken) as well as a maximum allowed
64 * tolerance. If tolerance is 'null', a default tolerance will be used.
65 */
66 public static Size getOptimalPreviewSize(Context context, Size[] sizes,
67 double targetRatio, Double aspectRatioTolerance) {
Sascha Haeberlinga5c41b82014-07-29 11:14:39 -070068 // TODO(andyhuibers): Don't hardcode this but use device's measurements.
69 final int MAX_ASPECT_HEIGHT = 1080;
70
71 // Count sizes with height <= 1080p to mimic camera1 api behavior.
72 int count = 0;
73 for (Size s : sizes) {
74 if (s.getHeight() <= MAX_ASPECT_HEIGHT) {
75 count++;
76 }
77 }
Sascha Haeberlingf2627902014-09-02 14:20:57 -070078 ArrayList<Size> camera1Sizes = new ArrayList<Size>(count);
Sascha Haeberlinga5c41b82014-07-29 11:14:39 -070079
80 // Set array of all sizes with height <= 1080p
81 for (Size s : sizes) {
82 if (s.getHeight() <= MAX_ASPECT_HEIGHT) {
Sascha Haeberlingf2627902014-09-02 14:20:57 -070083 camera1Sizes.add(new Size(s.getWidth(), s.getHeight()));
Sascha Haeberlinga5c41b82014-07-29 11:14:39 -070084 }
85 }
86
87 int optimalIndex = CameraUtil
Sascha Haeberlingc6da1a12014-11-06 09:50:51 -080088 .getOptimalPreviewSizeIndex(context, camera1Sizes, targetRatio,
89 aspectRatioTolerance);
Sascha Haeberlinga5c41b82014-07-29 11:14:39 -070090
91 if (optimalIndex == -1) {
92 return null;
93 }
94
Sascha Haeberlingf2627902014-09-02 14:20:57 -070095 Size optimal = camera1Sizes.get(optimalIndex);
Sascha Haeberlinga5c41b82014-07-29 11:14:39 -070096 for (Size s : sizes) {
Sascha Haeberlingf2627902014-09-02 14:20:57 -070097 if (s.getWidth() == optimal.getWidth() && s.getHeight() == optimal.getHeight()) {
Sascha Haeberlinga5c41b82014-07-29 11:14:39 -070098 return s;
99 }
100 }
101 return null;
102 }
103
104 /**
105 * Selects the preview buffer dimensions that are closest in size to the
106 * size of the view containing the preview.
107 */
108 public static Size pickBufferDimensions(Size[] supportedPreviewSizes,
109 double bestPreviewAspectRatio,
110 Context context) {
111 // Swap dimensions if the device is not in its natural orientation.
112 boolean swapDimens = (CameraUtil.getDisplayRotation(context) % 180) == 90;
113 // Swap dimensions if the device's natural orientation doesn't match
114 // the sensor orientation.
115 if (CaptureModuleUtil.getDeviceNaturalOrientation(context)
116 == Configuration.ORIENTATION_PORTRAIT) {
117 swapDimens = !swapDimens;
118 }
119 double bestAspect = bestPreviewAspectRatio;
120 if (swapDimens) {
121 bestAspect = 1 / bestAspect;
122 }
123
124 Size pick = CaptureModuleUtil.getOptimalPreviewSize(context, supportedPreviewSizes,
Sascha Haeberlingc6da1a12014-11-06 09:50:51 -0800125 bestPreviewAspectRatio, null);
Sascha Haeberlinga5c41b82014-07-29 11:14:39 -0700126 Log.d(TAG, "Picked buffer size: " + pick.toString());
127 return pick;
128 }
129}