Android Open Source - final_app Camera Configuration Manager






From Project

Back to project page final_app.

License

The source code is released under:

CC0 1.0 Universal Statement of Purpose The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent...

If you think the Android project final_app listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2010 ZXing authors//from   w w  w.  j  a  v a2 s .c  om
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.zxing.client.android.camera;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Point;
import android.hardware.Camera;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;

import com.google.zxing.client.android.PreferencesActivity;

/**
 * A class which deals with reading, parsing, and setting the camera parameters which are used to configure the camera hardware.
 */
final class CameraConfigurationManager {

  private static final String TAG = "CameraConfiguration";

  // This is bigger than the size of a small screen, which is still supported. The routine
  // below will still select the default (presumably 320x240) size for these. This prevents
  // accidental selection of very low resolution on some devices.
  private static final int MIN_PREVIEW_PIXELS = 480 * 320; // normal screen
  // private static final float MAX_EXPOSURE_COMPENSATION = 1.5f;
  // private static final float MIN_EXPOSURE_COMPENSATION = 0.0f;
  private static final double MAX_ASPECT_DISTORTION = 0.15;

  private final Context context;
  private Point screenResolution;
  private Point cameraResolution;

  CameraConfigurationManager(Context context) {
    this.context = context;
  }

  /**
   * Reads, one time, values from the camera that are needed by the app.
   */
  void initFromCameraParameters(Camera camera) {
    Camera.Parameters parameters = camera.getParameters();
    WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = manager.getDefaultDisplay();
    Point theScreenResolution = new Point();
    display.getSize(theScreenResolution);
    screenResolution = theScreenResolution;
    Log.i(TAG, "Screen resolution: " + screenResolution);
    cameraResolution = findBestPreviewSizeValue(parameters, screenResolution);
    Log.i(TAG, "Camera resolution: " + cameraResolution);
  }

  void setDesiredCameraParameters(Camera camera, boolean safeMode) {
    Camera.Parameters parameters = camera.getParameters();

    if (parameters == null) {
      Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
      return;
    }

    Log.i(TAG, "Initial camera parameters: " + parameters.flatten());

    if (safeMode) {
      Log.w(TAG, "In camera config safe mode -- most settings will not be honored");
    }

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

    initializeTorch(parameters, prefs, safeMode);

    String focusMode = null;
    if (prefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true)) {
      if (safeMode || prefs.getBoolean(PreferencesActivity.KEY_DISABLE_CONTINUOUS_FOCUS, false)) {
        focusMode = findSettableValue(parameters.getSupportedFocusModes(), Camera.Parameters.FOCUS_MODE_AUTO);
      } else {
        focusMode = findSettableValue(parameters.getSupportedFocusModes(), Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE,
            Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO, Camera.Parameters.FOCUS_MODE_AUTO);
      }
    }
    // Maybe selected auto-focus but not available, so fall through here:
    if (!safeMode && focusMode == null) {
      focusMode = findSettableValue(parameters.getSupportedFocusModes(), Camera.Parameters.FOCUS_MODE_MACRO, Camera.Parameters.FOCUS_MODE_EDOF);
    }
    if (focusMode != null) {
      parameters.setFocusMode(focusMode);
    }

    if (prefs.getBoolean(PreferencesActivity.KEY_INVERT_SCAN, false)) {
      String colorMode = findSettableValue(parameters.getSupportedColorEffects(), Camera.Parameters.EFFECT_NEGATIVE);
      if (colorMode != null) {
        parameters.setColorEffect(colorMode);
      }
    }

    parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
    camera.setParameters(parameters);

    Camera.Parameters afterParameters = camera.getParameters();
    Camera.Size afterSize = afterParameters.getPreviewSize();
    if (afterSize != null && (cameraResolution.x != afterSize.width || cameraResolution.y != afterSize.height)) {
      Log.w(TAG, "Camera said it supported preview size " + cameraResolution.x + 'x' + cameraResolution.y
          + ", but after setting it, preview size is " + afterSize.width + 'x' + afterSize.height);
      cameraResolution.x = afterSize.width;
      cameraResolution.y = afterSize.height;
    }
  }

  Point getCameraResolution() {
    return cameraResolution;
  }

  Point getScreenResolution() {
    return screenResolution;
  }

  boolean getTorchState(Camera camera) {
    if (camera != null) {
      Camera.Parameters parameters = camera.getParameters();
      if (parameters != null) {
        String flashMode = camera.getParameters().getFlashMode();
        return flashMode != null
            && (Camera.Parameters.FLASH_MODE_ON.equals(flashMode) || Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode));
      }
    }
    return false;
  }

  void setTorch(Camera camera, boolean newSetting) {
    Camera.Parameters parameters = camera.getParameters();
    doSetTorch(parameters, newSetting, false);
    camera.setParameters(parameters);
  }

  private void initializeTorch(Camera.Parameters parameters, SharedPreferences prefs, boolean safeMode) {
    boolean currentSetting = FrontLightMode.readPref(prefs) == FrontLightMode.ON;
    doSetTorch(parameters, currentSetting, safeMode);
  }

  private void doSetTorch(Camera.Parameters parameters, boolean newSetting, boolean safeMode) {
    String flashMode;
    if (newSetting) {
      flashMode = findSettableValue(parameters.getSupportedFlashModes(), Camera.Parameters.FLASH_MODE_TORCH, Camera.Parameters.FLASH_MODE_ON);
    } else {
      flashMode = findSettableValue(parameters.getSupportedFlashModes(), Camera.Parameters.FLASH_MODE_OFF);
    }
    if (flashMode != null) {
      parameters.setFlashMode(flashMode);
    }

    /*
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    if (!prefs.getBoolean(PreferencesActivity.KEY_DISABLE_EXPOSURE, false)) {
      if (!safeMode) {
        int minExposure = parameters.getMinExposureCompensation();
        int maxExposure = parameters.getMaxExposureCompensation();
        if (minExposure != 0 || maxExposure != 0) {
          float step = parameters.getExposureCompensationStep();
          int desiredCompensation;
          if (newSetting) {
            // Light on; set low exposue compensation
            desiredCompensation = Math.max((int) (MIN_EXPOSURE_COMPENSATION / step), minExposure);
          } else {
            // Light off; set high compensation
            desiredCompensation = Math.min((int) (MAX_EXPOSURE_COMPENSATION / step), maxExposure);
          }
          Log.i(TAG, "Setting exposure compensation to " + desiredCompensation + " / " + (step * desiredCompensation));
          parameters.setExposureCompensation(desiredCompensation);
        } else {
          Log.i(TAG, "Camera does not support exposure compensation");
        }
      }
    }
     */
  }

  private Point findBestPreviewSizeValue(Camera.Parameters parameters, Point screenResolution) {

    List<Camera.Size> rawSupportedSizes = parameters.getSupportedPreviewSizes();
    if (rawSupportedSizes == null) {
      Log.w(TAG, "Device returned no supported preview sizes; using default");
      Camera.Size defaultSize = parameters.getPreviewSize();
      return new Point(defaultSize.width, defaultSize.height);
    }

    // Sort by size, descending
    List<Camera.Size> supportedPreviewSizes = new ArrayList<Camera.Size>(rawSupportedSizes);
    Collections.sort(supportedPreviewSizes, new Comparator<Camera.Size>() {
      @Override
      public int compare(Camera.Size a, Camera.Size b) {
        int aPixels = a.height * a.width;
        int bPixels = b.height * b.width;
        if (bPixels < aPixels) {
          return -1;
        }
        if (bPixels > aPixels) {
          return 1;
        }
        return 0;
      }
    });

    if (Log.isLoggable(TAG, Log.INFO)) {
      StringBuilder previewSizesString = new StringBuilder();
      for (Camera.Size supportedPreviewSize : supportedPreviewSizes) {
        previewSizesString.append(supportedPreviewSize.width).append('x').append(supportedPreviewSize.height).append(' ');
      }
      Log.i(TAG, "Supported preview sizes: " + previewSizesString);
    }

    double screenAspectRatio = (double) screenResolution.x / (double) screenResolution.y;

    // Remove sizes that are unsuitable
    Iterator<Camera.Size> it = supportedPreviewSizes.iterator();
    while (it.hasNext()) {
      Camera.Size supportedPreviewSize = it.next();
      int realWidth = supportedPreviewSize.width;
      int realHeight = supportedPreviewSize.height;
      if (realWidth * realHeight < MIN_PREVIEW_PIXELS) {
        it.remove();
        continue;
      }

      boolean isCandidatePortrait = realWidth < realHeight;
      int maybeFlippedWidth = isCandidatePortrait ? realHeight : realWidth;
      int maybeFlippedHeight = isCandidatePortrait ? realWidth : realHeight;
      double aspectRatio = (double) maybeFlippedWidth / (double) maybeFlippedHeight;
      double distortion = Math.abs(aspectRatio - screenAspectRatio);
      if (distortion > MAX_ASPECT_DISTORTION) {
        it.remove();
        continue;
      }

      if (maybeFlippedWidth == screenResolution.x && maybeFlippedHeight == screenResolution.y) {
        Point exactPoint = new Point(realWidth, realHeight);
        Log.i(TAG, "Found preview size exactly matching screen size: " + exactPoint);
        return exactPoint;
      }
    }

    // If no exact match, use largest preview size. This was not a great idea on older devices because
    // of the additional computation needed. We're likely to get here on newer Android 4+ devices, where
    // the CPU is much more powerful.
    if (!supportedPreviewSizes.isEmpty()) {
      Camera.Size largestPreview = supportedPreviewSizes.get(0);
      Point largestSize = new Point(largestPreview.width, largestPreview.height);
      Log.i(TAG, "Using largest suitable preview size: " + largestSize);
      return largestSize;
    }

    // If there is nothing at all suitable, return current preview size
    Camera.Size defaultPreview = parameters.getPreviewSize();
    Point defaultSize = new Point(defaultPreview.width, defaultPreview.height);
    Log.i(TAG, "No suitable preview sizes, using default: " + defaultSize);
    return defaultSize;
  }

  private static String findSettableValue(Collection<String> supportedValues, String... desiredValues) {
    Log.i(TAG, "Supported values: " + supportedValues);
    String result = null;
    if (supportedValues != null) {
      for (String desiredValue : desiredValues) {
        if (supportedValues.contains(desiredValue)) {
          result = desiredValue;
          break;
        }
      }
    }
    Log.i(TAG, "Settable value: " + result);
    return result;
  }

}




Java Source Code List

com.google.zxing.client.android.AmbientLightManager.java
com.google.zxing.client.android.BeepManager.java
com.google.zxing.client.android.CaptureActivityHandler.java
com.google.zxing.client.android.CaptureActivity.java
com.google.zxing.client.android.Contents.java
com.google.zxing.client.android.DecodeFormatManager.java
com.google.zxing.client.android.DecodeHandler.java
com.google.zxing.client.android.DecodeHintManager.java
com.google.zxing.client.android.DecodeThread.java
com.google.zxing.client.android.FinishListener.java
com.google.zxing.client.android.HelpActivity.java
com.google.zxing.client.android.HttpHelper.java
com.google.zxing.client.android.InactivityTimer.java
com.google.zxing.client.android.IntentSource.java
com.google.zxing.client.android.Intents.java
com.google.zxing.client.android.LocaleManager.java
com.google.zxing.client.android.PreferencesActivity.java
com.google.zxing.client.android.PreferencesFragment.java
com.google.zxing.client.android.ScanFromWebPageManager.java
com.google.zxing.client.android.ViewfinderResultPointCallback.java
com.google.zxing.client.android.ViewfinderView.java
com.google.zxing.client.android.book.BrowseBookListener.java
com.google.zxing.client.android.book.SearchBookContentsActivity.java
com.google.zxing.client.android.book.SearchBookContentsAdapter.java
com.google.zxing.client.android.book.SearchBookContentsListItem.java
com.google.zxing.client.android.book.SearchBookContentsResult.java
com.google.zxing.client.android.camera.AutoFocusManager.java
com.google.zxing.client.android.camera.CameraConfigurationManager.java
com.google.zxing.client.android.camera.CameraManager.java
com.google.zxing.client.android.camera.FrontLightMode.java
com.google.zxing.client.android.camera.PreviewCallback.java
com.google.zxing.client.android.camera.open.OpenCameraInterface.java
com.google.zxing.client.android.clipboard.ClipboardInterface.java
com.google.zxing.client.android.encode.ContactEncoder.java
com.google.zxing.client.android.encode.EncodeActivity.java
com.google.zxing.client.android.encode.Formatter.java
com.google.zxing.client.android.encode.MECARDContactEncoder.java
com.google.zxing.client.android.encode.QRCodeEncoder.java
com.google.zxing.client.android.encode.VCardContactEncoder.java
com.google.zxing.client.android.history.DBHelper.java
com.google.zxing.client.android.history.HistoryActivity.java
com.google.zxing.client.android.history.HistoryItemAdapter.java
com.google.zxing.client.android.history.HistoryItem.java
com.google.zxing.client.android.history.HistoryManager.java
com.google.zxing.client.android.result.AddressBookResultHandler.java
com.google.zxing.client.android.result.CalendarResultHandler.java
com.google.zxing.client.android.result.EmailAddressResultHandler.java
com.google.zxing.client.android.result.GeoResultHandler.java
com.google.zxing.client.android.result.ISBNResultHandler.java
com.google.zxing.client.android.result.ProductResultHandler.java
com.google.zxing.client.android.result.ResultButtonListener.java
com.google.zxing.client.android.result.ResultHandlerFactory.java
com.google.zxing.client.android.result.ResultHandler.java
com.google.zxing.client.android.result.SMSResultHandler.java
com.google.zxing.client.android.result.TelResultHandler.java
com.google.zxing.client.android.result.TextResultHandler.java
com.google.zxing.client.android.result.URIResultHandler.java
com.google.zxing.client.android.result.WifiResultHandler.java
com.google.zxing.client.android.result.supplement.AmazonInfoRetriever.java
com.google.zxing.client.android.result.supplement.BookResultInfoRetriever.java
com.google.zxing.client.android.result.supplement.ProductResultInfoRetriever.java
com.google.zxing.client.android.result.supplement.SupplementalInfoRetriever.java
com.google.zxing.client.android.result.supplement.TitleRetriever.java
com.google.zxing.client.android.result.supplement.URIResultInfoRetriever.java
com.google.zxing.client.android.share.AppInfo.java
com.google.zxing.client.android.share.AppPickerActivity.java
com.google.zxing.client.android.share.BookmarkAdapter.java
com.google.zxing.client.android.share.BookmarkPickerActivity.java
com.google.zxing.client.android.share.LoadPackagesAsyncTask.java
com.google.zxing.client.android.share.ShareActivity.java
com.google.zxing.client.android.wifi.NetworkType.java
com.google.zxing.client.android.wifi.WifiConfigManager.java
com.google.zxing.integration.android.IntentIntegrator.java
com.google.zxing.integration.android.IntentResult.java
edu.cascadia.campusdirections.InstructionsFragment.java
edu.cascadia.campusdirections.MainActivity.java
edu.cascadia.campusdirections.SearchFragment.java
edu.cascadia.campusdirections.SplashScreen.java