mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Closes issue #484 : back-port almost all the orientaiton logic from BS+ to handle reverse-mounted cameras on devices like the Nexus 5X
This commit is contained in:
parent
f8623ccb12
commit
f58271e146
|
@ -37,6 +37,7 @@ import android.app.AlertDialog;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
@ -266,12 +267,22 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
|
||||||
|
|
||||||
private int getCurrentOrientation() {
|
private int getCurrentOrientation() {
|
||||||
int rotation = getWindowManager().getDefaultDisplay().getRotation();
|
int rotation = getWindowManager().getDefaultDisplay().getRotation();
|
||||||
switch (rotation) {
|
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||||
case Surface.ROTATION_0:
|
switch (rotation) {
|
||||||
case Surface.ROTATION_90:
|
case Surface.ROTATION_0:
|
||||||
return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
case Surface.ROTATION_90:
|
||||||
default:
|
return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||||
return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
default:
|
||||||
|
return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (rotation) {
|
||||||
|
case Surface.ROTATION_0:
|
||||||
|
case Surface.ROTATION_270:
|
||||||
|
return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||||
|
default:
|
||||||
|
return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,12 @@ import android.hardware.Camera;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
|
import android.view.Surface;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import com.google.zxing.client.android.PreferencesActivity;
|
import com.google.zxing.client.android.PreferencesActivity;
|
||||||
|
import com.google.zxing.client.android.camera.open.CameraFacing;
|
||||||
|
import com.google.zxing.client.android.camera.open.OpenCamera;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class which deals with reading, parsing, and setting the camera parameters which are used to
|
* A class which deals with reading, parsing, and setting the camera parameters which are used to
|
||||||
|
@ -36,8 +39,12 @@ final class CameraConfigurationManager {
|
||||||
private static final String TAG = "CameraConfiguration";
|
private static final String TAG = "CameraConfiguration";
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
private int cwNeededRotation;
|
||||||
|
private int cwRotationFromDisplayToCamera;
|
||||||
private Point screenResolution;
|
private Point screenResolution;
|
||||||
private Point cameraResolution;
|
private Point cameraResolution;
|
||||||
|
private Point bestPreviewSize;
|
||||||
|
private Point previewSizeOnScreen;
|
||||||
|
|
||||||
CameraConfigurationManager(Context context) {
|
CameraConfigurationManager(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
@ -46,20 +53,94 @@ final class CameraConfigurationManager {
|
||||||
/**
|
/**
|
||||||
* Reads, one time, values from the camera that are needed by the app.
|
* Reads, one time, values from the camera that are needed by the app.
|
||||||
*/
|
*/
|
||||||
void initFromCameraParameters(Camera camera) {
|
void initFromCameraParameters(OpenCamera camera) {
|
||||||
Camera.Parameters parameters = camera.getParameters();
|
Camera.Parameters parameters = camera.getCamera().getParameters();
|
||||||
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||||
Display display = manager.getDefaultDisplay();
|
Display display = manager.getDefaultDisplay();
|
||||||
|
|
||||||
|
int displayRotation = display.getRotation();
|
||||||
|
int cwRotationFromNaturalToDisplay;
|
||||||
|
switch (displayRotation) {
|
||||||
|
case Surface.ROTATION_0:
|
||||||
|
cwRotationFromNaturalToDisplay = 0;
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_90:
|
||||||
|
cwRotationFromNaturalToDisplay = 90;
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_180:
|
||||||
|
cwRotationFromNaturalToDisplay = 180;
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_270:
|
||||||
|
cwRotationFromNaturalToDisplay = 270;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Have seen this return incorrect values like -90
|
||||||
|
if (displayRotation % 90 == 0) {
|
||||||
|
cwRotationFromNaturalToDisplay = (360 + displayRotation) % 360;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Bad rotation: " + displayRotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.i(TAG, "Display at: " + cwRotationFromNaturalToDisplay);
|
||||||
|
|
||||||
|
int cwRotationFromNaturalToCamera = camera.getOrientation();
|
||||||
|
Log.i(TAG, "Camera at: " + cwRotationFromNaturalToCamera);
|
||||||
|
|
||||||
|
// Still not 100% sure about this. But acts like we need to flip this:
|
||||||
|
if (camera.getFacing() == CameraFacing.FRONT) {
|
||||||
|
cwRotationFromNaturalToCamera = (360 - cwRotationFromNaturalToCamera) % 360;
|
||||||
|
Log.i(TAG, "Front camera overriden to: " + cwRotationFromNaturalToCamera);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
String overrideRotationString;
|
||||||
|
if (camera.getFacing() == CameraFacing.FRONT) {
|
||||||
|
overrideRotationString = prefs.getString(PreferencesActivity.KEY_FORCE_CAMERA_ORIENTATION_FRONT, null);
|
||||||
|
} else {
|
||||||
|
overrideRotationString = prefs.getString(PreferencesActivity.KEY_FORCE_CAMERA_ORIENTATION, null);
|
||||||
|
}
|
||||||
|
if (overrideRotationString != null && !"-".equals(overrideRotationString)) {
|
||||||
|
Log.i(TAG, "Overriding camera manually to " + overrideRotationString);
|
||||||
|
cwRotationFromNaturalToCamera = Integer.parseInt(overrideRotationString);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
cwRotationFromDisplayToCamera =
|
||||||
|
(360 + cwRotationFromNaturalToCamera - cwRotationFromNaturalToDisplay) % 360;
|
||||||
|
Log.i(TAG, "Final display orientation: " + cwRotationFromDisplayToCamera);
|
||||||
|
if (camera.getFacing() == CameraFacing.FRONT) {
|
||||||
|
Log.i(TAG, "Compensating rotation for front camera");
|
||||||
|
cwNeededRotation = (360 - cwRotationFromDisplayToCamera) % 360;
|
||||||
|
} else {
|
||||||
|
cwNeededRotation = cwRotationFromDisplayToCamera;
|
||||||
|
}
|
||||||
|
Log.i(TAG, "Clockwise rotation from display to camera: " + cwNeededRotation);
|
||||||
|
|
||||||
Point theScreenResolution = new Point();
|
Point theScreenResolution = new Point();
|
||||||
display.getSize(theScreenResolution);
|
display.getSize(theScreenResolution);
|
||||||
screenResolution = theScreenResolution;
|
screenResolution = theScreenResolution;
|
||||||
Log.i(TAG, "Screen resolution: " + screenResolution);
|
Log.i(TAG, "Screen resolution in current orientation: " + screenResolution);
|
||||||
cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
|
cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
|
||||||
Log.i(TAG, "Camera resolution: " + cameraResolution);
|
Log.i(TAG, "Camera resolution: " + cameraResolution);
|
||||||
|
bestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
|
||||||
|
Log.i(TAG, "Best available preview size: " + bestPreviewSize);
|
||||||
|
|
||||||
|
boolean isScreenPortrait = screenResolution.x < screenResolution.y;
|
||||||
|
boolean isPreviewSizePortrait = bestPreviewSize.x < bestPreviewSize.y;
|
||||||
|
|
||||||
|
if (isScreenPortrait == isPreviewSizePortrait) {
|
||||||
|
previewSizeOnScreen = bestPreviewSize;
|
||||||
|
} else {
|
||||||
|
previewSizeOnScreen = new Point(bestPreviewSize.y, bestPreviewSize.x);
|
||||||
|
}
|
||||||
|
Log.i(TAG, "Preview size on screen: " + previewSizeOnScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDesiredCameraParameters(Camera camera, boolean safeMode) {
|
void setDesiredCameraParameters(OpenCamera camera, boolean safeMode) {
|
||||||
Camera.Parameters parameters = camera.getParameters();
|
|
||||||
|
Camera theCamera = camera.getCamera();
|
||||||
|
Camera.Parameters parameters = theCamera.getParameters();
|
||||||
|
|
||||||
if (parameters == null) {
|
if (parameters == null) {
|
||||||
Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
|
Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
|
||||||
|
@ -99,22 +180,30 @@ final class CameraConfigurationManager {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
|
parameters.setPreviewSize(bestPreviewSize.x, bestPreviewSize.y);
|
||||||
|
|
||||||
Log.i(TAG, "Final camera parameters: " + parameters.flatten());
|
theCamera.setParameters(parameters);
|
||||||
|
|
||||||
camera.setParameters(parameters);
|
theCamera.setDisplayOrientation(cwRotationFromDisplayToCamera);
|
||||||
|
|
||||||
Camera.Parameters afterParameters = camera.getParameters();
|
Camera.Parameters afterParameters = theCamera.getParameters();
|
||||||
Camera.Size afterSize = afterParameters.getPreviewSize();
|
Camera.Size afterSize = afterParameters.getPreviewSize();
|
||||||
if (afterSize!= null && (cameraResolution.x != afterSize.width || cameraResolution.y != afterSize.height)) {
|
if (afterSize != null && (bestPreviewSize.x != afterSize.width || bestPreviewSize.y != afterSize.height)) {
|
||||||
Log.w(TAG, "Camera said it supported preview size " + cameraResolution.x + 'x' + cameraResolution.y +
|
Log.w(TAG, "Camera said it supported preview size " + bestPreviewSize.x + 'x' + bestPreviewSize.y +
|
||||||
", but after setting it, preview size is " + afterSize.width + 'x' + afterSize.height);
|
", but after setting it, preview size is " + afterSize.width + 'x' + afterSize.height);
|
||||||
cameraResolution.x = afterSize.width;
|
bestPreviewSize.x = afterSize.width;
|
||||||
cameraResolution.y = afterSize.height;
|
bestPreviewSize.y = afterSize.height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point getBestPreviewSize() {
|
||||||
|
return bestPreviewSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point getPreviewSizeOnScreen() {
|
||||||
|
return previewSizeOnScreen;
|
||||||
|
}
|
||||||
|
|
||||||
Point getCameraResolution() {
|
Point getCameraResolution() {
|
||||||
return cameraResolution;
|
return cameraResolution;
|
||||||
}
|
}
|
||||||
|
@ -123,11 +212,15 @@ final class CameraConfigurationManager {
|
||||||
return screenResolution;
|
return screenResolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getCWNeededRotation() {
|
||||||
|
return cwNeededRotation;
|
||||||
|
}
|
||||||
|
|
||||||
boolean getTorchState(Camera camera) {
|
boolean getTorchState(Camera camera) {
|
||||||
if (camera != null) {
|
if (camera != null) {
|
||||||
Camera.Parameters parameters = camera.getParameters();
|
Camera.Parameters parameters = camera.getParameters();
|
||||||
if (parameters != null) {
|
if (parameters != null) {
|
||||||
String flashMode = parameters.getFlashMode();
|
String flashMode = camera.getParameters().getFlashMode();
|
||||||
return flashMode != null &&
|
return flashMode != null &&
|
||||||
(Camera.Parameters.FLASH_MODE_ON.equals(flashMode) ||
|
(Camera.Parameters.FLASH_MODE_ON.equals(flashMode) ||
|
||||||
Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode));
|
Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode));
|
||||||
|
|
|
@ -24,6 +24,7 @@ import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import com.google.zxing.PlanarYUVLuminanceSource;
|
import com.google.zxing.PlanarYUVLuminanceSource;
|
||||||
|
import com.google.zxing.client.android.camera.open.OpenCamera;
|
||||||
import com.google.zxing.client.android.camera.open.OpenCameraInterface;
|
import com.google.zxing.client.android.camera.open.OpenCameraInterface;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -46,7 +47,7 @@ public final class CameraManager {
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final CameraConfigurationManager configManager;
|
private final CameraConfigurationManager configManager;
|
||||||
private Camera camera;
|
private OpenCamera camera;
|
||||||
private AutoFocusManager autoFocusManager;
|
private AutoFocusManager autoFocusManager;
|
||||||
private Rect framingRect;
|
private Rect framingRect;
|
||||||
private Rect framingRectInPreview;
|
private Rect framingRectInPreview;
|
||||||
|
@ -74,16 +75,14 @@ public final class CameraManager {
|
||||||
* @throws IOException Indicates the camera driver failed to open.
|
* @throws IOException Indicates the camera driver failed to open.
|
||||||
*/
|
*/
|
||||||
public synchronized void openDriver(SurfaceHolder holder) throws IOException {
|
public synchronized void openDriver(SurfaceHolder holder) throws IOException {
|
||||||
Camera theCamera = camera;
|
OpenCamera theCamera = camera;
|
||||||
if (theCamera == null) {
|
if (theCamera == null) {
|
||||||
|
|
||||||
theCamera = OpenCameraInterface.open(requestedCameraId);
|
theCamera = OpenCameraInterface.open(requestedCameraId);
|
||||||
if (theCamera == null) {
|
if (theCamera == null) {
|
||||||
throw new IOException();
|
throw new IOException("Camera.open() failed to return object from driver");
|
||||||
}
|
}
|
||||||
camera = theCamera;
|
camera = theCamera;
|
||||||
}
|
}
|
||||||
theCamera.setPreviewDisplay(holder);
|
|
||||||
|
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
@ -95,7 +94,8 @@ public final class CameraManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera.Parameters parameters = theCamera.getParameters();
|
Camera cameraObject = theCamera.getCamera();
|
||||||
|
Camera.Parameters parameters = cameraObject.getParameters();
|
||||||
String parametersFlattened = parameters == null ? null : parameters.flatten(); // Save these, temporarily
|
String parametersFlattened = parameters == null ? null : parameters.flatten(); // Save these, temporarily
|
||||||
try {
|
try {
|
||||||
configManager.setDesiredCameraParameters(theCamera, false);
|
configManager.setDesiredCameraParameters(theCamera, false);
|
||||||
|
@ -105,10 +105,10 @@ public final class CameraManager {
|
||||||
Log.i(TAG, "Resetting to saved camera params: " + parametersFlattened);
|
Log.i(TAG, "Resetting to saved camera params: " + parametersFlattened);
|
||||||
// Reset:
|
// Reset:
|
||||||
if (parametersFlattened != null) {
|
if (parametersFlattened != null) {
|
||||||
parameters = theCamera.getParameters();
|
parameters = cameraObject.getParameters();
|
||||||
parameters.unflatten(parametersFlattened);
|
parameters.unflatten(parametersFlattened);
|
||||||
try {
|
try {
|
||||||
theCamera.setParameters(parameters);
|
cameraObject.setParameters(parameters);
|
||||||
configManager.setDesiredCameraParameters(theCamera, true);
|
configManager.setDesiredCameraParameters(theCamera, true);
|
||||||
} catch (RuntimeException re2) {
|
} catch (RuntimeException re2) {
|
||||||
// Well, darn. Give up
|
// Well, darn. Give up
|
||||||
|
@ -116,6 +116,7 @@ public final class CameraManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cameraObject.setPreviewDisplay(holder);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ public final class CameraManager {
|
||||||
*/
|
*/
|
||||||
public synchronized void closeDriver() {
|
public synchronized void closeDriver() {
|
||||||
if (camera != null) {
|
if (camera != null) {
|
||||||
camera.release();
|
camera.getCamera().release();
|
||||||
camera = null;
|
camera = null;
|
||||||
// Make sure to clear these each time we close the camera, so that any scanning rect
|
// Make sure to clear these each time we close the camera, so that any scanning rect
|
||||||
// requested by intent is forgotten.
|
// requested by intent is forgotten.
|
||||||
|
@ -141,11 +142,11 @@ public final class CameraManager {
|
||||||
* Asks the camera hardware to begin drawing preview frames to the screen.
|
* Asks the camera hardware to begin drawing preview frames to the screen.
|
||||||
*/
|
*/
|
||||||
public synchronized void startPreview() {
|
public synchronized void startPreview() {
|
||||||
Camera theCamera = camera;
|
OpenCamera theCamera = camera;
|
||||||
if (theCamera != null && !previewing) {
|
if (theCamera != null && !previewing) {
|
||||||
theCamera.startPreview();
|
theCamera.getCamera().startPreview();
|
||||||
previewing = true;
|
previewing = true;
|
||||||
autoFocusManager = new AutoFocusManager(context, camera);
|
autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +159,7 @@ public final class CameraManager {
|
||||||
autoFocusManager = null;
|
autoFocusManager = null;
|
||||||
}
|
}
|
||||||
if (camera != null && previewing) {
|
if (camera != null && previewing) {
|
||||||
camera.stopPreview();
|
camera.getCamera().stopPreview();
|
||||||
previewCallback.setHandler(null, 0);
|
previewCallback.setHandler(null, 0);
|
||||||
previewing = false;
|
previewing = false;
|
||||||
}
|
}
|
||||||
|
@ -170,12 +171,13 @@ public final class CameraManager {
|
||||||
* @param newSetting if {@code true}, light should be turned on if currently off. And vice versa.
|
* @param newSetting if {@code true}, light should be turned on if currently off. And vice versa.
|
||||||
*/
|
*/
|
||||||
public synchronized void setTorch(boolean newSetting) {
|
public synchronized void setTorch(boolean newSetting) {
|
||||||
if (newSetting != configManager.getTorchState(camera)) {
|
OpenCamera theCamera = camera;
|
||||||
if (camera != null) {
|
if (theCamera != null) {
|
||||||
|
if (newSetting != configManager.getTorchState(theCamera.getCamera())) {
|
||||||
if (autoFocusManager != null) {
|
if (autoFocusManager != null) {
|
||||||
autoFocusManager.stop();
|
autoFocusManager.stop();
|
||||||
}
|
}
|
||||||
configManager.setTorch(camera, newSetting);
|
configManager.setTorch(theCamera.getCamera(), newSetting);
|
||||||
if (autoFocusManager != null) {
|
if (autoFocusManager != null) {
|
||||||
autoFocusManager.start();
|
autoFocusManager.start();
|
||||||
}
|
}
|
||||||
|
@ -192,10 +194,10 @@ public final class CameraManager {
|
||||||
* @param message The what field of the message to be sent.
|
* @param message The what field of the message to be sent.
|
||||||
*/
|
*/
|
||||||
public synchronized void requestPreviewFrame(Handler handler, int message) {
|
public synchronized void requestPreviewFrame(Handler handler, int message) {
|
||||||
Camera theCamera = camera;
|
OpenCamera theCamera = camera;
|
||||||
if (theCamera != null && previewing) {
|
if (theCamera != null && previewing) {
|
||||||
previewCallback.setHandler(handler, message);
|
previewCallback.setHandler(handler, message);
|
||||||
theCamera.setOneShotPreviewCallback(previewCallback);
|
theCamera.getCamera().setOneShotPreviewCallback(previewCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
24
android/src/com/google/zxing/client/android/camera/open/CameraFacing.java
Executable file
24
android/src/com/google/zxing/client/android/camera/open/CameraFacing.java
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 ZXing authors
|
||||||
|
*
|
||||||
|
* 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.open;
|
||||||
|
|
||||||
|
public enum CameraFacing {
|
||||||
|
|
||||||
|
BACK, // must be value 0!
|
||||||
|
FRONT, // must be value 1!
|
||||||
|
|
||||||
|
}
|
52
android/src/com/google/zxing/client/android/camera/open/OpenCamera.java
Executable file
52
android/src/com/google/zxing/client/android/camera/open/OpenCamera.java
Executable file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 ZXing authors
|
||||||
|
*
|
||||||
|
* 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.open;
|
||||||
|
|
||||||
|
import android.hardware.Camera;
|
||||||
|
|
||||||
|
public final class OpenCamera {
|
||||||
|
|
||||||
|
private final int index;
|
||||||
|
private final Camera camera;
|
||||||
|
private final CameraFacing facing;
|
||||||
|
private final int orientation;
|
||||||
|
|
||||||
|
public OpenCamera(int index, Camera camera, CameraFacing facing, int orientation) {
|
||||||
|
this.index = index;
|
||||||
|
this.camera = camera;
|
||||||
|
this.facing = facing;
|
||||||
|
this.orientation = orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Camera getCamera() {
|
||||||
|
return camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CameraFacing getFacing() {
|
||||||
|
return facing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOrientation() {
|
||||||
|
return orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Camera #" + index + " : " + facing + ',' + orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -36,8 +36,8 @@ public final class OpenCameraInterface {
|
||||||
* or {@link #NO_REQUESTED_CAMERA} means "no preference"
|
* or {@link #NO_REQUESTED_CAMERA} means "no preference"
|
||||||
* @return handle to {@link Camera} that was opened
|
* @return handle to {@link Camera} that was opened
|
||||||
*/
|
*/
|
||||||
public static Camera open(int cameraId) {
|
public static OpenCamera open(int cameraId) {
|
||||||
|
|
||||||
int numCameras = Camera.getNumberOfCameras();
|
int numCameras = Camera.getNumberOfCameras();
|
||||||
if (numCameras == 0) {
|
if (numCameras == 0) {
|
||||||
Log.w(TAG, "No cameras!");
|
Log.w(TAG, "No cameras!");
|
||||||
|
@ -46,36 +46,44 @@ public final class OpenCameraInterface {
|
||||||
|
|
||||||
boolean explicitRequest = cameraId >= 0;
|
boolean explicitRequest = cameraId >= 0;
|
||||||
|
|
||||||
if (!explicitRequest) {
|
Camera.CameraInfo selectedCameraInfo = null;
|
||||||
// Select a camera if no explicit camera requested
|
int index = 0;
|
||||||
int index = 0;
|
while (index < numCameras) {
|
||||||
while (index < numCameras) {
|
if (cameraId == NO_REQUESTED_CAMERA || index == cameraId) {
|
||||||
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
|
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
|
||||||
Camera.getCameraInfo(index, cameraInfo);
|
Camera.getCameraInfo(index, cameraInfo);
|
||||||
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
|
CameraFacing reportedFacing = CameraFacing.values()[cameraInfo.facing];
|
||||||
|
if (reportedFacing == CameraFacing.BACK) {
|
||||||
|
selectedCameraInfo = cameraInfo;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
|
index++;
|
||||||
cameraId = index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera camera;
|
Camera camera;
|
||||||
if (cameraId < numCameras) {
|
if (index < numCameras) {
|
||||||
Log.i(TAG, "Opening camera #" + cameraId);
|
Log.i(TAG, "Opening camera #" + index);
|
||||||
camera = Camera.open(cameraId);
|
camera = Camera.open(index);
|
||||||
} else {
|
} else {
|
||||||
if (explicitRequest) {
|
if (explicitRequest) {
|
||||||
Log.w(TAG, "Requested camera does not exist: " + cameraId);
|
Log.w(TAG, "Requested camera does not exist: " + cameraId);
|
||||||
camera = null;
|
camera = null;
|
||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "No camera facing back; returning camera #0");
|
Log.i(TAG, "No camera facing " + CameraFacing.BACK + "; returning camera #0");
|
||||||
camera = Camera.open(0);
|
camera = Camera.open(0);
|
||||||
|
selectedCameraInfo = new Camera.CameraInfo();
|
||||||
|
Camera.getCameraInfo(0, selectedCameraInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return camera;
|
if (camera == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new OpenCamera(index,
|
||||||
|
camera,
|
||||||
|
CameraFacing.values()[selectedCameraInfo.facing],
|
||||||
|
selectedCameraInfo.orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -349,7 +349,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.simpligility.maven.plugins</groupId>
|
<groupId>com.simpligility.maven.plugins</groupId>
|
||||||
<artifactId>android-maven-plugin</artifactId>
|
<artifactId>android-maven-plugin</artifactId>
|
||||||
<version>4.2.1</version>
|
<version>4.3.0</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
|
Loading…
Reference in a new issue