2 * Copyright (C) 2010 ZXing authors
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.evergreen.android.barcodescan.camera;
18 import java.util.Collection;
20 import org.evergreen.android.barcodescan.PreferencesActivity;
22 import android.content.Context;
23 import android.content.SharedPreferences;
24 import android.graphics.Point;
25 import android.hardware.Camera;
26 import android.preference.PreferenceManager;
27 import android.util.Log;
28 import android.view.Display;
29 import android.view.WindowManager;
32 * A class which deals with reading, parsing, and setting the camera parameters which are used to
33 * configure the camera hardware.
35 final class CameraConfigurationManager {
37 private static final String TAG = "CameraConfiguration";
38 private static final int MIN_PREVIEW_PIXELS = 320 * 240; // small screen
39 private static final int MAX_PREVIEW_PIXELS = 800 * 480; // large/HD screen
41 private final Context context;
42 private Point screenResolution;
43 private Point cameraResolution;
45 CameraConfigurationManager(Context context) {
46 this.context = context;
50 * Reads, one time, values from the camera that are needed by the app.
52 void initFromCameraParameters(Camera camera) {
53 Camera.Parameters parameters = camera.getParameters();
54 WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
55 Display display = manager.getDefaultDisplay();
56 int width = display.getWidth();
57 int height = display.getHeight();
58 // We're landscape-only, and have apparently seen issues with display thinking it's portrait
59 // when waking from sleep. If it's not landscape, assume it's mistaken and reverse them:
61 Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect");
66 screenResolution = new Point(width, height);
67 Log.i(TAG, "Screen resolution: " + screenResolution);
68 cameraResolution = findBestPreviewSizeValue(parameters, screenResolution, false);
69 Log.i(TAG, "Camera resolution: " + cameraResolution);
72 void setDesiredCameraParameters(Camera camera) {
73 Camera.Parameters parameters = camera.getParameters();
75 if (parameters == null) {
76 Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
80 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
82 initializeTorch(parameters, prefs);
83 String focusMode = findSettableValue(parameters.getSupportedFocusModes(),
84 Camera.Parameters.FOCUS_MODE_AUTO,
85 Camera.Parameters.FOCUS_MODE_MACRO);
86 if (focusMode != null) {
87 parameters.setFocusMode(focusMode);
90 parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
91 camera.setParameters(parameters);
94 Point getCameraResolution() {
95 return cameraResolution;
98 Point getScreenResolution() {
99 return screenResolution;
102 void setTorch(Camera camera, boolean newSetting) {
103 Camera.Parameters parameters = camera.getParameters();
104 doSetTorch(parameters, newSetting);
105 camera.setParameters(parameters);
106 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
107 boolean currentSetting = prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false);
108 if (currentSetting != newSetting) {
109 SharedPreferences.Editor editor = prefs.edit();
110 editor.putBoolean(PreferencesActivity.KEY_FRONT_LIGHT, newSetting);
115 private static void initializeTorch(Camera.Parameters parameters, SharedPreferences prefs) {
116 boolean currentSetting = prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false);
117 doSetTorch(parameters, currentSetting);
120 private static void doSetTorch(Camera.Parameters parameters, boolean newSetting) {
123 flashMode = findSettableValue(parameters.getSupportedFlashModes(),
124 Camera.Parameters.FLASH_MODE_TORCH,
125 Camera.Parameters.FLASH_MODE_ON);
127 flashMode = findSettableValue(parameters.getSupportedFlashModes(),
128 Camera.Parameters.FLASH_MODE_OFF);
130 if (flashMode != null) {
131 parameters.setFlashMode(flashMode);
135 private static Point findBestPreviewSizeValue(Camera.Parameters parameters,
136 Point screenResolution,
138 Point bestSize = null;
139 int diff = Integer.MAX_VALUE;
140 for (Camera.Size supportedPreviewSize : parameters.getSupportedPreviewSizes()) {
141 int pixels = supportedPreviewSize.height * supportedPreviewSize.width;
142 if (pixels < MIN_PREVIEW_PIXELS || pixels > MAX_PREVIEW_PIXELS) {
145 int supportedWidth = portrait ? supportedPreviewSize.height : supportedPreviewSize.width;
146 int supportedHeight = portrait ? supportedPreviewSize.width : supportedPreviewSize.height;
147 int newDiff = Math.abs(screenResolution.x * supportedHeight - supportedWidth * screenResolution.y);
149 bestSize = new Point(supportedWidth, supportedHeight);
152 if (newDiff < diff) {
153 bestSize = new Point(supportedWidth, supportedHeight);
157 if (bestSize == null) {
158 Camera.Size defaultSize = parameters.getPreviewSize();
159 bestSize = new Point(defaultSize.width, defaultSize.height);
164 private static String findSettableValue(Collection<String> supportedValues,
165 String... desiredValues) {
166 Log.i(TAG, "Supported values: " + supportedValues);
167 String result = null;
168 if (supportedValues != null) {
169 for (String desiredValue : desiredValues) {
170 if (supportedValues.contains(desiredValue)) {
171 result = desiredValue;
176 Log.i(TAG, "Settable value: " + result);