Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) 2010 ZXing authors
      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 
     17 package com.google.zxing.client.android.camera;
     18 
     19 import android.content.Context;
     20 import android.content.SharedPreferences;
     21 import android.graphics.Point;
     22 import android.hardware.Camera;
     23 import android.preference.PreferenceManager;
     24 import android.util.Log;
     25 import android.view.Display;
     26 import android.view.WindowManager;
     27 
     28 import java.util.Collection;
     29 
     30 /**
     31  * A class which deals with reading, parsing, and setting the camera parameters which are used to
     32  * configure the camera hardware.
     33  */
     34 final class CameraConfigurationManager {
     35 
     36   private static final String TAG = "CameraConfiguration";
     37   private static final int MIN_PREVIEW_PIXELS = 320 * 240; // small screen
     38   private static final int MAX_PREVIEW_PIXELS = 800 * 480; // large/HD screen
     39 
     40   private final Context context;
     41   private Point screenResolution;
     42   private Point cameraResolution;
     43 
     44   CameraConfigurationManager(Context context) {
     45     this.context = context;
     46   }
     47 
     48   /**
     49    * Reads, one time, values from the camera that are needed by the app.
     50    */
     51   void initFromCameraParameters(Camera camera) {
     52     Camera.Parameters parameters = camera.getParameters();
     53     WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
     54     Display display = manager.getDefaultDisplay();
     55     int width = display.getWidth();
     56     int height = display.getHeight();
     57     // We're landscape-only, and have apparently seen issues with display thinking it's portrait
     58     // when waking from sleep. If it's not landscape, assume it's mistaken and reverse them:
     59     if (width < height) {
     60       Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect");
     61       int temp = width;
     62       width = height;
     63       height = temp;
     64     }
     65     screenResolution = new Point(width, height);
     66     Log.i(TAG, "Screen resolution: " + screenResolution);
     67     cameraResolution = findBestPreviewSizeValue(parameters, screenResolution, false);
     68     Log.i(TAG, "Camera resolution: " + cameraResolution);
     69   }
     70 
     71   void setDesiredCameraParameters(Camera camera) {
     72     Camera.Parameters parameters = camera.getParameters();
     73 
     74     if (parameters == null) {
     75       Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
     76       return;
     77     }
     78 
     79     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
     80 
     81     initializeTorch(parameters, prefs);
     82     String focusMode = findSettableValue(parameters.getSupportedFocusModes(),
     83                                          Camera.Parameters.FOCUS_MODE_AUTO,
     84                                          Camera.Parameters.FOCUS_MODE_MACRO);
     85     if (focusMode != null) {
     86       parameters.setFocusMode(focusMode);
     87     }
     88 
     89     parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
     90     camera.setParameters(parameters);
     91   }
     92 
     93   Point getCameraResolution() {
     94     return cameraResolution;
     95   }
     96 
     97   Point getScreenResolution() {
     98     return screenResolution;
     99   }
    100 
    101   void setTorch(Camera camera, boolean newSetting) {
    102     Camera.Parameters parameters = camera.getParameters();
    103     doSetTorch(parameters, newSetting);
    104     camera.setParameters(parameters);
    105     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    106     boolean currentSetting = false; // prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false);
    107 //    if (currentSetting != newSetting) {
    108 //      SharedPreferences.Editor editor = prefs.edit();
    109 //      editor.putBoolean(PreferencesActivity.KEY_FRONT_LIGHT, newSetting);
    110 //      editor.commit();
    111 //    }
    112   }
    113 
    114   private static void initializeTorch(Camera.Parameters parameters, SharedPreferences prefs) {
    115     boolean currentSetting = false;// prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false);
    116     doSetTorch(parameters, currentSetting);
    117   }
    118 
    119   private static void doSetTorch(Camera.Parameters parameters, boolean newSetting) {
    120     String flashMode;
    121     if (newSetting) {
    122       flashMode = findSettableValue(parameters.getSupportedFlashModes(),
    123                                     Camera.Parameters.FLASH_MODE_TORCH,
    124                                     Camera.Parameters.FLASH_MODE_ON);
    125     } else {
    126       flashMode = findSettableValue(parameters.getSupportedFlashModes(),
    127                                     Camera.Parameters.FLASH_MODE_OFF);
    128     }
    129     if (flashMode != null) {
    130       parameters.setFlashMode(flashMode);
    131     }
    132   }
    133 
    134   private static Point findBestPreviewSizeValue(Camera.Parameters parameters,
    135                                                 Point screenResolution,
    136                                                 boolean portrait) {
    137     Point bestSize = null;
    138     int diff = Integer.MAX_VALUE;
    139     for (Camera.Size supportedPreviewSize : parameters.getSupportedPreviewSizes()) {
    140       int pixels = supportedPreviewSize.height * supportedPreviewSize.width;
    141       if (pixels < MIN_PREVIEW_PIXELS || pixels > MAX_PREVIEW_PIXELS) {
    142         continue;
    143       }
    144       int supportedWidth = portrait ? supportedPreviewSize.height : supportedPreviewSize.width;
    145       int supportedHeight = portrait ? supportedPreviewSize.width : supportedPreviewSize.height;
    146       int newDiff = Math.abs(screenResolution.x * supportedHeight - supportedWidth * screenResolution.y);
    147       if (newDiff == 0) {
    148         bestSize = new Point(supportedWidth, supportedHeight);
    149         break;
    150       }
    151       if (newDiff < diff) {
    152         bestSize = new Point(supportedWidth, supportedHeight);
    153         diff = newDiff;
    154       }
    155     }
    156     if (bestSize == null) {
    157       Camera.Size defaultSize = parameters.getPreviewSize();
    158       bestSize = new Point(defaultSize.width, defaultSize.height);
    159     }
    160     return bestSize;
    161   }
    162 
    163   private static String findSettableValue(Collection<String> supportedValues,
    164                                           String... desiredValues) {
    165     Log.i(TAG, "Supported values: " + supportedValues);
    166     String result = null;
    167     if (supportedValues != null) {
    168       for (String desiredValue : desiredValues) {
    169         if (supportedValues.contains(desiredValue)) {
    170           result = desiredValue;
    171           break;
    172         }
    173       }
    174     }
    175     Log.i(TAG, "Settable value: " + result);
    176     return result;
    177   }
    178 
    179 }
    180