Android Open Source - bitfynd-wallet-android Camera Manager






From Project

Back to project page bitfynd-wallet-android.

License

The source code is released under:

GNU General Public License

If you think the Android project bitfynd-wallet-android 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 2012-2014 the original author or authors.
 *//w ww .  j a  v  a 2 s.  co m
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.schildbach.wallet.camera;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.annotation.SuppressLint;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PreviewCallback;
import android.view.SurfaceHolder;

import com.google.zxing.PlanarYUVLuminanceSource;

/**
 * @author Andreas Schildbach
 */
public final class CameraManager
{
  private static final int MIN_FRAME_SIZE = 240;
  private static final int MAX_FRAME_SIZE = 600;
  private static final int MIN_PREVIEW_PIXELS = 470 * 320; // normal screen
  private static final int MAX_PREVIEW_PIXELS = 1280 * 720;

  private Camera camera;
  private Camera.Size cameraResolution;
  private Rect frame;
  private Rect framePreview;

  private static final Logger log = LoggerFactory.getLogger(CameraManager.class);

  public Rect getFrame()
  {
    return frame;
  }

  public Rect getFramePreview()
  {
    return framePreview;
  }

  public Camera open(final SurfaceHolder holder, final boolean continuousAutoFocus) throws IOException
  {
    // try back-facing camera
    camera = Camera.open();

    // fall back to using front-facing camera
    if (camera == null)
    {
      final int cameraCount = Camera.getNumberOfCameras();
      final CameraInfo cameraInfo = new CameraInfo();

      // search for front-facing camera
      for (int i = 0; i < cameraCount; i++)
      {
        Camera.getCameraInfo(i, cameraInfo);
        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
        {
          camera = Camera.open(i);
          break;
        }
      }
    }

    camera.setPreviewDisplay(holder);

    final Camera.Parameters parameters = camera.getParameters();

    final Rect surfaceFrame = holder.getSurfaceFrame();
    cameraResolution = findBestPreviewSizeValue(parameters, surfaceFrame);

    final int surfaceWidth = surfaceFrame.width();
    final int surfaceHeight = surfaceFrame.height();

    final int rawSize = Math.min(surfaceWidth * 2 / 3, surfaceHeight * 2 / 3);
    final int frameSize = Math.max(MIN_FRAME_SIZE, Math.min(MAX_FRAME_SIZE, rawSize));

    final int leftOffset = (surfaceWidth - frameSize) / 2;
    final int topOffset = (surfaceHeight - frameSize) / 2;
    frame = new Rect(leftOffset, topOffset, leftOffset + frameSize, topOffset + frameSize);
    framePreview = new Rect(frame.left * cameraResolution.width / surfaceWidth, frame.top * cameraResolution.height / surfaceHeight, frame.right
        * cameraResolution.width / surfaceWidth, frame.bottom * cameraResolution.height / surfaceHeight);

    final String savedParameters = parameters == null ? null : parameters.flatten();

    try
    {
      setDesiredCameraParameters(camera, cameraResolution, continuousAutoFocus);
    }
    catch (final RuntimeException x)
    {
      if (savedParameters != null)
      {
        final Camera.Parameters parameters2 = camera.getParameters();
        parameters2.unflatten(savedParameters);
        try
        {
          camera.setParameters(parameters2);
          setDesiredCameraParameters(camera, cameraResolution, continuousAutoFocus);
        }
        catch (final RuntimeException x2)
        {
          log.info("problem setting camera parameters", x2);
        }
      }
    }

    camera.startPreview();

    return camera;
  }

  public void close()
  {
    if (camera != null)
    {
      try
      {
        camera.stopPreview();
      }
      catch (final RuntimeException x)
      {
        log.warn("something went wrong while stopping camera preview", x);
      }

      camera.release();
    }
  }

  private static final Comparator<Camera.Size> numPixelComparator = new Comparator<Camera.Size>()
  {
    @Override
    public int compare(final Camera.Size size1, final Camera.Size size2)
    {
      final int pixels1 = size1.height * size1.width;
      final int pixels2 = size2.height * size2.width;

      if (pixels1 < pixels2)
        return 1;
      else if (pixels1 > pixels2)
        return -1;
      else
        return 0;
    }
  };

  private static Camera.Size findBestPreviewSizeValue(final Camera.Parameters parameters, Rect surfaceResolution)
  {
    if (surfaceResolution.height() > surfaceResolution.width())
      surfaceResolution = new Rect(0, 0, surfaceResolution.height(), surfaceResolution.width());

    final float screenAspectRatio = (float) surfaceResolution.width() / (float) surfaceResolution.height();

    final List<Camera.Size> rawSupportedSizes = parameters.getSupportedPreviewSizes();
    if (rawSupportedSizes == null)
      return parameters.getPreviewSize();

    // sort by size, descending
    final List<Camera.Size> supportedPreviewSizes = new ArrayList<Camera.Size>(rawSupportedSizes);
    Collections.sort(supportedPreviewSizes, numPixelComparator);

    Camera.Size bestSize = null;
    float diff = Float.POSITIVE_INFINITY;

    for (final Camera.Size supportedPreviewSize : supportedPreviewSizes)
    {
      final int realWidth = supportedPreviewSize.width;
      final int realHeight = supportedPreviewSize.height;
      final int realPixels = realWidth * realHeight;
      if (realPixels < MIN_PREVIEW_PIXELS || realPixels > MAX_PREVIEW_PIXELS)
        continue;

      final boolean isCandidatePortrait = realWidth < realHeight;
      final int maybeFlippedWidth = isCandidatePortrait ? realHeight : realWidth;
      final int maybeFlippedHeight = isCandidatePortrait ? realWidth : realHeight;
      if (maybeFlippedWidth == surfaceResolution.width() && maybeFlippedHeight == surfaceResolution.height())
        return supportedPreviewSize;

      final float aspectRatio = (float) maybeFlippedWidth / (float) maybeFlippedHeight;
      final float newDiff = Math.abs(aspectRatio - screenAspectRatio);
      if (newDiff < diff)
      {
        bestSize = supportedPreviewSize;
        diff = newDiff;
      }
    }

    if (bestSize != null)
      return bestSize;
    else
      return parameters.getPreviewSize();
  }

  @SuppressLint("InlinedApi")
  private static void setDesiredCameraParameters(final Camera camera, final Camera.Size cameraResolution, final boolean continuousAutoFocus)
  {
    final Camera.Parameters parameters = camera.getParameters();
    if (parameters == null)
      return;

    final List<String> supportedFocusModes = parameters.getSupportedFocusModes();
    final String focusMode = continuousAutoFocus ? findValue(supportedFocusModes, Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE,
        Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO, Camera.Parameters.FOCUS_MODE_AUTO, Camera.Parameters.FOCUS_MODE_MACRO) : findValue(
        supportedFocusModes, Camera.Parameters.FOCUS_MODE_AUTO, Camera.Parameters.FOCUS_MODE_MACRO);
    if (focusMode != null)
      parameters.setFocusMode(focusMode);

    parameters.setPreviewSize(cameraResolution.width, cameraResolution.height);

    camera.setParameters(parameters);
  }

  public void requestPreviewFrame(final PreviewCallback callback)
  {
    camera.setOneShotPreviewCallback(callback);
  }

  public PlanarYUVLuminanceSource buildLuminanceSource(final byte[] data)
  {
    return new PlanarYUVLuminanceSource(data, cameraResolution.width, cameraResolution.height, framePreview.left, framePreview.top,
        framePreview.width(), framePreview.height(), false);
  }

  public void setTorch(final boolean enabled)
  {
    if (enabled != getTorchEnabled(camera))
      setTorchEnabled(camera, enabled);
  }

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

    return false;
  }

  private static void setTorchEnabled(final Camera camera, final boolean enabled)
  {
    final Camera.Parameters parameters = camera.getParameters();

    final List<String> supportedFlashModes = parameters.getSupportedFlashModes();
    if (supportedFlashModes != null)
    {
      final String flashMode;
      if (enabled)
        flashMode = findValue(supportedFlashModes, Camera.Parameters.FLASH_MODE_TORCH, Camera.Parameters.FLASH_MODE_ON);
      else
        flashMode = findValue(supportedFlashModes, Camera.Parameters.FLASH_MODE_OFF);

      if (flashMode != null)
      {
        camera.cancelAutoFocus(); // autofocus can cause conflict

        parameters.setFlashMode(flashMode);
        camera.setParameters(parameters);
      }
    }
  }

  private static String findValue(final Collection<String> values, final String... valuesToFind)
  {
    for (final String valueToFind : valuesToFind)
      if (values.contains(valueToFind))
        return valueToFind;

    return null;
  }
}




Java Source Code List

de.schildbach.wallet.AddressBookProvider.java
de.schildbach.wallet.Configuration.java
de.schildbach.wallet.Constants.java
de.schildbach.wallet.ExchangeRatesProvider.java
de.schildbach.wallet.FileAttachmentProvider.java
de.schildbach.wallet.WalletApplication.java
de.schildbach.wallet.WalletBalanceWidgetProvider.java
de.schildbach.wallet.camera.CameraManager.java
de.schildbach.wallet.data.PaymentIntent.java
de.schildbach.wallet.integration.android.BitcoinIntegration.java
de.schildbach.wallet.offline.AcceptBluetoothService.java
de.schildbach.wallet.offline.AcceptBluetoothThread.java
de.schildbach.wallet.offline.DirectPaymentTask.java
de.schildbach.wallet.service.AutosyncReceiver.java
de.schildbach.wallet.service.BlockchainServiceImpl.java
de.schildbach.wallet.service.BlockchainService.java
de.schildbach.wallet.service.BlockchainStateLoader.java
de.schildbach.wallet.service.BlockchainState.java
de.schildbach.wallet.service.UpgradeWalletService.java
de.schildbach.wallet.ui.AbstractBindServiceActivity.java
de.schildbach.wallet.ui.AbstractWalletActivity.java
de.schildbach.wallet.ui.AddressAndLabel.java
de.schildbach.wallet.ui.AddressBookActivity.java
de.schildbach.wallet.ui.BlockListFragment.java
de.schildbach.wallet.ui.CurrencyAmountView.java
de.schildbach.wallet.ui.CurrencyCalculatorLink.java
de.schildbach.wallet.ui.CurrencySymbolDrawable.java
de.schildbach.wallet.ui.CurrencyTextView.java
de.schildbach.wallet.ui.DialogBuilder.java
de.schildbach.wallet.ui.EditAddressBookEntryFragment.java
de.schildbach.wallet.ui.EncryptKeysDialogFragment.java
de.schildbach.wallet.ui.ExchangeRateLoader.java
de.schildbach.wallet.ui.ExchangeRatesActivity.java
de.schildbach.wallet.ui.ExchangeRatesFragment.java
de.schildbach.wallet.ui.FancyListFragment.java
de.schildbach.wallet.ui.FileAdapter.java
de.schildbach.wallet.ui.HelpDialogFragment.java
de.schildbach.wallet.ui.ImportDialogButtonEnablerListener.java
de.schildbach.wallet.ui.InputParser.java
de.schildbach.wallet.ui.MaybeMaintenanceFragment.java
de.schildbach.wallet.ui.NetworkMonitorActivity.java
de.schildbach.wallet.ui.PeerListFragment.java
de.schildbach.wallet.ui.ProgressDialogFragment.java
de.schildbach.wallet.ui.ReportIssueDialogBuilder.java
de.schildbach.wallet.ui.RequestCoinsActivity.java
de.schildbach.wallet.ui.RequestCoinsFragment.java
de.schildbach.wallet.ui.RestoreWalletActivity.java
de.schildbach.wallet.ui.ScanActivity.java
de.schildbach.wallet.ui.ScannerView.java
de.schildbach.wallet.ui.SendCoinsQrActivity.java
de.schildbach.wallet.ui.SendingAddressesFragment.java
de.schildbach.wallet.ui.ShowPasswordCheckListener.java
de.schildbach.wallet.ui.TransactionsListAdapter.java
de.schildbach.wallet.ui.TransactionsListFragment.java
de.schildbach.wallet.ui.WalletActionsFragment.java
de.schildbach.wallet.ui.WalletActivity.java
de.schildbach.wallet.ui.WalletAddressFragment.java
de.schildbach.wallet.ui.WalletAddressesAdapter.java
de.schildbach.wallet.ui.WalletAddressesFragment.java
de.schildbach.wallet.ui.WalletBalanceFragment.java
de.schildbach.wallet.ui.WalletBalanceLoader.java
de.schildbach.wallet.ui.WalletDisclaimerFragment.java
de.schildbach.wallet.ui.WalletTransactionsFragment.java
de.schildbach.wallet.ui.preference.AboutFragment.java
de.schildbach.wallet.ui.preference.DiagnosticsFragment.java
de.schildbach.wallet.ui.preference.PreferenceActivity.java
de.schildbach.wallet.ui.preference.SettingsFragment.java
de.schildbach.wallet.ui.send.DecodePrivateKeyTask.java
de.schildbach.wallet.ui.send.DeriveKeyTask.java
de.schildbach.wallet.ui.send.MaintenanceDialogFragment.java
de.schildbach.wallet.ui.send.RequestPaymentRequestTask.java
de.schildbach.wallet.ui.send.RequestWalletBalanceTask.java
de.schildbach.wallet.ui.send.SendCoinsActivity.java
de.schildbach.wallet.ui.send.SendCoinsFragment.java
de.schildbach.wallet.ui.send.SendCoinsOfflineTask.java
de.schildbach.wallet.ui.send.SweepWalletActivity.java
de.schildbach.wallet.ui.send.SweepWalletFragment.java
de.schildbach.wallet.util.Base43.java
de.schildbach.wallet.util.BitmapFragment.java
de.schildbach.wallet.util.Bluetooth.java
de.schildbach.wallet.util.CircularProgressView.java
de.schildbach.wallet.util.CrashReporter.java
de.schildbach.wallet.util.Crypto.java
de.schildbach.wallet.util.Formats.java
de.schildbach.wallet.util.GenericUtils.java
de.schildbach.wallet.util.HttpGetThread.java
de.schildbach.wallet.util.Io.java
de.schildbach.wallet.util.Iso8601Format.java
de.schildbach.wallet.util.LinuxSecureRandom.java
de.schildbach.wallet.util.MonetarySpannable.java
de.schildbach.wallet.util.Nfc.java
de.schildbach.wallet.util.Qr.java
de.schildbach.wallet.util.ThrottlingWalletChangeListener.java
de.schildbach.wallet.util.ViewPagerTabs.java
de.schildbach.wallet.util.WalletUtils.java
de.schildbach.wallet.util.WholeStringBuilder.java