OCR Configurable  1.0
 Todo Clases Namespaces Archivos Funciones Variables
CameraConfigurationManager.java
Ir a la documentación de este archivo.
00001 /*
00002  * Copyright (C) 2010 ZXing authors
00003  * Copyright 2011 Robert Theis
00004  * Copyright 2012 Jaime Navarro Santapau
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *      http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00026 package edu.uoc.ocr.camera;
00027 
00028 import android.content.Context;
00029 import android.content.SharedPreferences;
00030 import android.graphics.Point;
00031 import android.hardware.Camera;
00032 import android.preference.PreferenceManager;
00033 import android.util.Log;
00034 import android.view.Display;
00035 import android.view.WindowManager;
00036 
00037 import edu.uoc.ocr.PreferencesActivity;
00038 
00039 import java.util.ArrayList;
00040 import java.util.Collection;
00041 import java.util.Collections;
00042 import java.util.Comparator;
00043 import java.util.List;
00044 
00051 final class CameraConfigurationManager {
00052 
00053         private static final String TAG = "CameraConfiguration";
00054         // This is bigger than the size of a small screen, which is still supported.
00055         // The routine
00056         // below will still select the default (presumably 320x240) size for these.
00057         // This prevents
00058         // accidental selection of very low resolution on some devices.
00059         private static final int MIN_PREVIEW_PIXELS = 470 * 320; // normal screen
00060         private static final int MAX_PREVIEW_PIXELS = 800 * 600; // more than
00061                                                                                                                                 // large/HD
00062                                                                                                                                 // screen
00063 
00064         private final Context context;
00065         private Point screenResolution;
00066         private Point cameraResolution;
00067 
00068         CameraConfigurationManager(Context context) {
00069                 this.context = context;
00070         }
00071 
00076         void initFromCameraParameters(Camera camera) {
00077                 Camera.Parameters parameters = camera.getParameters();
00078                 WindowManager manager = (WindowManager) context
00079                                 .getSystemService(Context.WINDOW_SERVICE);
00080                 Display display = manager.getDefaultDisplay();
00081                 int width = display.getWidth();
00082                 int height = display.getHeight();
00083                 // We're landscape-only, and have apparently seen issues with display
00084                 // thinking it's portrait
00085                 // when waking from sleep. If it's not landscape, assume it's mistaken
00086                 // and reverse them:
00087                 if (width < height) {
00088                         Log.i(TAG,
00089                                         "Display reports portrait orientation; assuming this is incorrect");
00090                         int temp = width;
00091                         width = height;
00092                         height = temp;
00093                 }
00094                 screenResolution = new Point(width, height);
00095                 Log.i(TAG, "Screen resolution: " + screenResolution);
00096                 cameraResolution = findBestPreviewSizeValue(parameters,
00097                                 screenResolution);
00098                 Log.i(TAG, "Camera resolution: " + cameraResolution);
00099         }
00100 
00101         void setDesiredCameraParameters(Camera camera) {
00102                 Camera.Parameters parameters = camera.getParameters();
00103 
00104                 if (parameters == null) {
00105                         Log.w(TAG,
00106                                         "Device error: no camera parameters are available. Proceeding without configuration.");
00107                         return;
00108                 }
00109 
00110                 SharedPreferences prefs = PreferenceManager
00111                                 .getDefaultSharedPreferences(context);
00112 
00113                 initializeTorch(parameters, prefs);
00114                 String focusMode = null;
00115                 if (prefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true)) {
00116                         focusMode = findSettableValue(parameters.getSupportedFocusModes(),
00117                                         "continuous-video", // Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO
00118                                                                                 // in 4.0+
00119                                         "continuous-picture", // Camera.Paramters.FOCUS_MODE_CONTINUOUS_PICTURE
00120                                                                                         // in 4.0+
00121                                         Camera.Parameters.FOCUS_MODE_AUTO);
00122                 }
00123                 // Maybe selected auto-focus but not available, so fall through here:
00124                 if (focusMode == null) {
00125                         focusMode = findSettableValue(parameters.getSupportedFocusModes(),
00126                                         Camera.Parameters.FOCUS_MODE_MACRO, "edof"); // Camera.Parameters.FOCUS_MODE_EDOF
00127                                                                                                                                         // in 2.2+
00128                 }
00129                 if (focusMode != null) {
00130                         parameters.setFocusMode(focusMode);
00131                 }
00132 
00133                 parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
00134                 camera.setParameters(parameters);
00135         }
00136 
00137         Point getCameraResolution() {
00138                 return cameraResolution;
00139         }
00140 
00141         Point getScreenResolution() {
00142                 return screenResolution;
00143         }
00144 
00145         void setTorch(Camera camera, boolean newSetting) {
00146                 Camera.Parameters parameters = camera.getParameters();
00147                 doSetTorch(parameters, newSetting);
00148                 camera.setParameters(parameters);
00149                 SharedPreferences prefs = PreferenceManager
00150                                 .getDefaultSharedPreferences(context);
00151                 boolean currentSetting = prefs.getBoolean(
00152                                 PreferencesActivity.KEY_TOGGLE_LIGHT, false);
00153                 if (currentSetting != newSetting) {
00154                         SharedPreferences.Editor editor = prefs.edit();
00155                         editor.putBoolean(PreferencesActivity.KEY_TOGGLE_LIGHT, newSetting);
00156                         editor.commit();
00157                 }
00158         }
00159 
00160         private static void initializeTorch(Camera.Parameters parameters,
00161                         SharedPreferences prefs) {
00162                 boolean currentSetting = prefs.getBoolean(
00163                                 PreferencesActivity.KEY_TOGGLE_LIGHT, false);
00164                 doSetTorch(parameters, currentSetting);
00165         }
00166 
00167         private static void doSetTorch(Camera.Parameters parameters,
00168                         boolean newSetting) {
00169                 String flashMode;
00170                 if (newSetting) {
00171                         flashMode = findSettableValue(parameters.getSupportedFlashModes(),
00172                                         Camera.Parameters.FLASH_MODE_TORCH,
00173                                         Camera.Parameters.FLASH_MODE_ON);
00174                 } else {
00175                         flashMode = findSettableValue(parameters.getSupportedFlashModes(),
00176                                         Camera.Parameters.FLASH_MODE_OFF);
00177                 }
00178                 if (flashMode != null) {
00179                         parameters.setFlashMode(flashMode);
00180                 }
00181         }
00182 
00183         private Point findBestPreviewSizeValue(Camera.Parameters parameters,
00184                         Point screenResolution) {
00185 
00186                 // Sort by size, descending
00187                 List<Camera.Size> supportedPreviewSizes = new ArrayList<Camera.Size>(
00188                                 parameters.getSupportedPreviewSizes());
00189                 Collections.sort(supportedPreviewSizes, new Comparator<Camera.Size>() {
00190                         @Override
00191                         public int compare(Camera.Size a, Camera.Size b) {
00192                                 int aPixels = a.height * a.width;
00193                                 int bPixels = b.height * b.width;
00194                                 if (bPixels < aPixels) {
00195                                         return -1;
00196                                 }
00197                                 if (bPixels > aPixels) {
00198                                         return 1;
00199                                 }
00200                                 return 0;
00201                         }
00202                 });
00203 
00204                 if (Log.isLoggable(TAG, Log.INFO)) {
00205                         StringBuilder previewSizesString = new StringBuilder();
00206                         for (Camera.Size supportedPreviewSize : supportedPreviewSizes) {
00207                                 previewSizesString.append(supportedPreviewSize.width)
00208                                                 .append('x').append(supportedPreviewSize.height)
00209                                                 .append(' ');
00210                         }
00211                         Log.i(TAG, "Supported preview sizes: " + previewSizesString);
00212                 }
00213 
00214                 Point bestSize = null;
00215                 float screenAspectRatio = (float) screenResolution.x
00216                                 / (float) screenResolution.y;
00217 
00218                 float diff = Float.POSITIVE_INFINITY;
00219                 for (Camera.Size supportedPreviewSize : supportedPreviewSizes) {
00220                         int realWidth = supportedPreviewSize.width;
00221                         int realHeight = supportedPreviewSize.height;
00222                         int pixels = realWidth * realHeight;
00223                         if (pixels < MIN_PREVIEW_PIXELS || pixels > MAX_PREVIEW_PIXELS) {
00224                                 continue;
00225                         }
00226                         boolean isCandidatePortrait = realWidth < realHeight;
00227                         int maybeFlippedWidth = isCandidatePortrait ? realHeight
00228                                         : realWidth;
00229                         int maybeFlippedHeight = isCandidatePortrait ? realWidth
00230                                         : realHeight;
00231                         if (maybeFlippedWidth == screenResolution.x
00232                                         && maybeFlippedHeight == screenResolution.y) {
00233                                 Point exactPoint = new Point(realWidth, realHeight);
00234                                 Log.i(TAG, "Found preview size exactly matching screen size: "
00235                                                 + exactPoint);
00236                                 return exactPoint;
00237                         }
00238                         float aspectRatio = (float) maybeFlippedWidth
00239                                         / (float) maybeFlippedHeight;
00240                         float newDiff = Math.abs(aspectRatio - screenAspectRatio);
00241                         if (newDiff < diff) {
00242                                 bestSize = new Point(realWidth, realHeight);
00243                                 diff = newDiff;
00244                         }
00245                 }
00246 
00247                 if (bestSize == null) {
00248                         Camera.Size defaultSize = parameters.getPreviewSize();
00249                         bestSize = new Point(defaultSize.width, defaultSize.height);
00250                         Log.i(TAG, "No suitable preview sizes, using default: " + bestSize);
00251                 }
00252 
00253                 Log.i(TAG, "Found best approximate preview size: " + bestSize);
00254                 return bestSize;
00255         }
00256 
00257         private static String findSettableValue(Collection<String> supportedValues,
00258                         String... desiredValues) {
00259                 Log.i(TAG, "Supported values: " + supportedValues);
00260                 String result = null;
00261                 if (supportedValues != null) {
00262                         for (String desiredValue : desiredValues) {
00263                                 if (supportedValues.contains(desiredValue)) {
00264                                         result = desiredValue;
00265                                         break;
00266                                 }
00267                         }
00268                 }
00269                 Log.i(TAG, "Settable value: " + result);
00270                 return result;
00271         }
00272 
00273 }
 Todo Clases Namespaces Archivos Funciones Variables