You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
9.2 KiB
279 lines
9.2 KiB
/*
|
|
* Copyright (C) 2010 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.geogle.zxing.camera;
|
|
|
|
import android.content.Context;
|
|
import android.graphics.Point;
|
|
import android.hardware.Camera;
|
|
import android.os.Build;
|
|
import android.util.Log;
|
|
import android.view.Display;
|
|
import android.view.WindowManager;
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
final class CameraConfigurationManager {
|
|
|
|
private static final String TAG = CameraConfigurationManager.class.getSimpleName();
|
|
|
|
private static final int TEN_DESIRED_ZOOM = 27;
|
|
private static final int DESIRED_SHARPNESS = 30;
|
|
|
|
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
|
|
|
private final Context context;
|
|
private Point screenResolution;
|
|
private Point cameraResolution;
|
|
private int previewFormat;
|
|
private String previewFormatString;
|
|
|
|
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();
|
|
previewFormat = parameters.getPreviewFormat();
|
|
previewFormatString = parameters.get("preview-format");
|
|
Log.d(TAG, "Default preview format: " + previewFormat + '/' + previewFormatString);
|
|
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
|
Display display = manager.getDefaultDisplay();
|
|
screenResolution = new Point(display.getWidth(), display.getHeight());
|
|
Log.d(TAG, "Screen resolution: " + screenResolution);
|
|
|
|
//图片拉伸
|
|
Point screenResolutionForCamera = new Point();
|
|
screenResolutionForCamera.x = screenResolution.x;
|
|
screenResolutionForCamera.y = screenResolution.y;
|
|
// preview size is always something like 480*320, other 320*480
|
|
if (screenResolution.x < screenResolution.y) {
|
|
screenResolutionForCamera.x = screenResolution.y;
|
|
screenResolutionForCamera.y = screenResolution.x;
|
|
}
|
|
|
|
cameraResolution = getCameraResolution(parameters, screenResolutionForCamera);
|
|
Log.d(TAG, "Camera resolution: " + screenResolution);
|
|
|
|
}
|
|
|
|
/**
|
|
* Sets the camera up to take preview images which are used for both preview and decoding.
|
|
* We detect the preview format here so that buildLuminanceSource() can build an appropriate
|
|
* LuminanceSource subclass. In the future we may want to force YUV420SP as it's the smallest,
|
|
* and the planar Y can be used for barcode scanning without a copy in some cases.
|
|
*/
|
|
void setDesiredCameraParameters(Camera camera) {
|
|
Camera.Parameters parameters = camera.getParameters();
|
|
Log.d(TAG, "Setting preview size: " + cameraResolution);
|
|
parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
|
|
setFlash(parameters);
|
|
setZoom(parameters);
|
|
//setSharpness(parameters);
|
|
//modify here
|
|
camera.setDisplayOrientation(90);
|
|
camera.setParameters(parameters);
|
|
}
|
|
|
|
Point getCameraResolution() {
|
|
return cameraResolution;
|
|
}
|
|
|
|
Point getScreenResolution() {
|
|
return screenResolution;
|
|
}
|
|
|
|
int getPreviewFormat() {
|
|
return previewFormat;
|
|
}
|
|
|
|
String getPreviewFormatString() {
|
|
return previewFormatString;
|
|
}
|
|
|
|
private static Point getCameraResolution(Camera.Parameters parameters, Point screenResolution) {
|
|
|
|
String previewSizeValueString = parameters.get("preview-size-values");
|
|
// saw this on Xperia
|
|
if (previewSizeValueString == null) {
|
|
previewSizeValueString = parameters.get("preview-size-value");
|
|
}
|
|
|
|
Point cameraResolution = null;
|
|
|
|
if (previewSizeValueString != null) {
|
|
Log.d(TAG, "preview-size-values parameter: " + previewSizeValueString);
|
|
cameraResolution = findBestPreviewSizeValue(previewSizeValueString, screenResolution);
|
|
}
|
|
|
|
if (cameraResolution == null) {
|
|
// Ensure that the camera resolution is a multiple of 8, as the screen may not be.
|
|
cameraResolution = new Point(
|
|
(screenResolution.x >> 3) << 3,
|
|
(screenResolution.y >> 3) << 3);
|
|
}
|
|
|
|
return cameraResolution;
|
|
}
|
|
|
|
private static Point findBestPreviewSizeValue(CharSequence previewSizeValueString, Point screenResolution) {
|
|
int bestX = 0;
|
|
int bestY = 0;
|
|
int diff = Integer.MAX_VALUE;
|
|
for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) {
|
|
|
|
previewSize = previewSize.trim();
|
|
int dimPosition = previewSize.indexOf('x');
|
|
if (dimPosition < 0) {
|
|
Log.w(TAG, "Bad preview-size: " + previewSize);
|
|
continue;
|
|
}
|
|
|
|
int newX;
|
|
int newY;
|
|
try {
|
|
newX = Integer.parseInt(previewSize.substring(0, dimPosition));
|
|
newY = Integer.parseInt(previewSize.substring(dimPosition + 1));
|
|
} catch (NumberFormatException nfe) {
|
|
Log.w(TAG, "Bad preview-size: " + previewSize);
|
|
continue;
|
|
}
|
|
|
|
int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y);
|
|
if (newDiff == 0) {
|
|
bestX = newX;
|
|
bestY = newY;
|
|
break;
|
|
} else if (newDiff < diff) {
|
|
bestX = newX;
|
|
bestY = newY;
|
|
diff = newDiff;
|
|
}
|
|
|
|
}
|
|
|
|
if (bestX > 0 && bestY > 0) {
|
|
return new Point(bestX, bestY);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static int findBestMotZoomValue(CharSequence stringValues, int tenDesiredZoom) {
|
|
int tenBestValue = 0;
|
|
for (String stringValue : COMMA_PATTERN.split(stringValues)) {
|
|
stringValue = stringValue.trim();
|
|
double value;
|
|
try {
|
|
value = Double.parseDouble(stringValue);
|
|
} catch (NumberFormatException nfe) {
|
|
return tenDesiredZoom;
|
|
}
|
|
int tenValue = (int) (10.0 * value);
|
|
if (Math.abs(tenDesiredZoom - value) < Math.abs(tenDesiredZoom - tenBestValue)) {
|
|
tenBestValue = tenValue;
|
|
}
|
|
}
|
|
return tenBestValue;
|
|
}
|
|
|
|
private void setFlash(Camera.Parameters parameters) {
|
|
// FIXME: This is a hack to turn the flash off on the Samsung Galaxy.
|
|
// And this is a hack-hack to work around a different value on the Behold II
|
|
// Restrict Behold II check to Cupcake, per Samsung's advice
|
|
//if (Build.MODEL.contains("Behold II") &&
|
|
// CameraManager.SDK_INT == Build.VERSION_CODES.CUPCAKE) {
|
|
if (Build.MODEL.contains("Behold II") && CameraManager.SDK_INT == 3) { // 3 = Cupcake
|
|
parameters.set("flash-value", 1);
|
|
} else {
|
|
parameters.set("flash-value", 2);
|
|
}
|
|
// This is the standard setting to turn the flash off that all devices should honor.
|
|
parameters.set("flash-mode", "off");
|
|
}
|
|
|
|
private void setZoom(Camera.Parameters parameters) {
|
|
|
|
String zoomSupportedString = parameters.get("zoom-supported");
|
|
if (zoomSupportedString != null && !Boolean.parseBoolean(zoomSupportedString)) {
|
|
return;
|
|
}
|
|
|
|
int tenDesiredZoom = TEN_DESIRED_ZOOM;
|
|
|
|
String maxZoomString = parameters.get("max-zoom");
|
|
if (maxZoomString != null) {
|
|
try {
|
|
int tenMaxZoom = (int) (10.0 * Double.parseDouble(maxZoomString));
|
|
if (tenDesiredZoom > tenMaxZoom) {
|
|
tenDesiredZoom = tenMaxZoom;
|
|
}
|
|
} catch (NumberFormatException nfe) {
|
|
Log.w(TAG, "Bad max-zoom: " + maxZoomString);
|
|
}
|
|
}
|
|
|
|
String takingPictureZoomMaxString = parameters.get("taking-picture-zoom-max");
|
|
if (takingPictureZoomMaxString != null) {
|
|
try {
|
|
int tenMaxZoom = Integer.parseInt(takingPictureZoomMaxString);
|
|
if (tenDesiredZoom > tenMaxZoom) {
|
|
tenDesiredZoom = tenMaxZoom;
|
|
}
|
|
} catch (NumberFormatException nfe) {
|
|
Log.w(TAG, "Bad taking-picture-zoom-max: " + takingPictureZoomMaxString);
|
|
}
|
|
}
|
|
|
|
String motZoomValuesString = parameters.get("mot-zoom-values");
|
|
if (motZoomValuesString != null) {
|
|
tenDesiredZoom = findBestMotZoomValue(motZoomValuesString, tenDesiredZoom);
|
|
}
|
|
|
|
String motZoomStepString = parameters.get("mot-zoom-step");
|
|
if (motZoomStepString != null) {
|
|
try {
|
|
double motZoomStep = Double.parseDouble(motZoomStepString.trim());
|
|
int tenZoomStep = (int) (10.0 * motZoomStep);
|
|
if (tenZoomStep > 1) {
|
|
tenDesiredZoom -= tenDesiredZoom % tenZoomStep;
|
|
}
|
|
} catch (NumberFormatException nfe) {
|
|
// continue
|
|
}
|
|
}
|
|
|
|
// Set zoom. This helps encourage the user to pull back.
|
|
// Some devices like the Behold have a zoom parameter
|
|
if (maxZoomString != null || motZoomValuesString != null) {
|
|
parameters.set("zoom", String.valueOf(tenDesiredZoom / 10.0));
|
|
}
|
|
|
|
// Most devices, like the Hero, appear to expose this zoom parameter.
|
|
// It takes on values like "27" which appears to mean 2.7x zoom
|
|
if (takingPictureZoomMaxString != null) {
|
|
parameters.set("taking-picture-zoom", tenDesiredZoom);
|
|
}
|
|
}
|
|
|
|
public static int getDesiredSharpness() {
|
|
return DESIRED_SHARPNESS;
|
|
}
|
|
|
|
}
|