优化细节

This commit is contained in:
Jenly
2020-12-17 00:34:26 +08:00
parent 4d607cf849
commit 7c87efa216
21 changed files with 243 additions and 256 deletions

View File

@@ -18,15 +18,12 @@ package com.king.zxing;
import android.content.Context;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.preference.PreferenceManager;
import com.king.zxing.camera.CameraManager;
import com.king.zxing.camera.FrontLightMode;
/**
* Detects ambient light and switches on the front light when very dark, and off again when sufficiently light.
@@ -36,6 +33,8 @@ import com.king.zxing.camera.FrontLightMode;
*/
final class AmbientLightManager implements SensorEventListener {
private static final int INTERVAL_TIME = 200;
protected static final float TOO_DARK_LUX = 45.0f;
protected static final float BRIGHT_ENOUGH_LUX = 100.0f;
@@ -52,19 +51,18 @@ final class AmbientLightManager implements SensorEventListener {
private CameraManager cameraManager;
private Sensor lightSensor;
private long lastTime;
AmbientLightManager(Context context) {
this.context = context;
}
void start(CameraManager cameraManager) {
this.cameraManager = cameraManager;
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
if (FrontLightMode.readPref(sharedPrefs) == FrontLightMode.AUTO) {
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
if (lightSensor != null) {
sensorManager.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
if (lightSensor != null) {
sensorManager.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
@@ -79,6 +77,12 @@ final class AmbientLightManager implements SensorEventListener {
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
long currentTime = System.currentTimeMillis();
if(currentTime - lastTime < INTERVAL_TIME){//降低频率
return;
}
lastTime = currentTime;
float ambientLightLux = sensorEvent.values[0];
if (cameraManager != null) {
if (ambientLightLux <= tooDarkLux) {

View File

@@ -16,16 +16,13 @@ package com.king.zxing;
*/
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import com.king.zxing.util.LogUtils;
@@ -37,9 +34,7 @@ import java.io.IOException;
*/
public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable {
private static final String TAG = BeepManager.class.getSimpleName();
private static final float BEEP_VOLUME = 0.10f;
// private static final float BEEP_VOLUME = 0.10f;
private static final long VIBRATE_DURATION = 200L;
private final Activity activity;
@@ -62,8 +57,8 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
}
synchronized void updatePrefs() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
shouldBeep(prefs, activity);
// SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
// shouldBeep(prefs, activity);
// vibrate = prefs.getBoolean(Preferences.KEY_VIBRATE, false);
if (playBeep && mediaPlayer == null) {
// The volume on STREAM_SYSTEM is not adjustable, and users found it too loud,
@@ -77,6 +72,7 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
if (playBeep && mediaPlayer != null) {
mediaPlayer.start();
}
LogUtils.d("vibrate:" + vibrate);
if (vibrate) {
Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_DURATION);
@@ -95,7 +91,6 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
return shouldPlayBeep;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private MediaPlayer buildMediaPlayer(Context activity) {
MediaPlayer mediaPlayer = new MediaPlayer();
try (AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.zxl_beep)) {
@@ -103,7 +98,7 @@ public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(false);
mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
// mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
mediaPlayer.prepare();
return mediaPlayer;
} catch (IOException ioe) {

View File

@@ -20,6 +20,7 @@ import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import com.google.zxing.Result;
import com.king.zxing.camera.CameraManager;
import androidx.annotation.LayoutRes;
@@ -62,7 +63,6 @@ public class CaptureActivity extends AppCompatActivity implements OnCaptureCallb
int ivTorchId = getIvTorchId();
if(ivTorchId != 0){
ivTorch = findViewById(ivTorchId);
ivTorch.setVisibility(View.INVISIBLE);
}
initCaptureHelper();
}
@@ -161,7 +161,7 @@ public class CaptureActivity extends AppCompatActivity implements OnCaptureCallb
* @return 返回true表示拦截将不自动执行后续逻辑为false表示不拦截默认不拦截
*/
@Override
public boolean onResultCallback(String result) {
public boolean onResultCallback(Result result) {
return false;
}
}

View File

@@ -21,6 +21,7 @@ import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import com.google.zxing.Result;
import com.king.zxing.camera.CameraManager;
import androidx.annotation.LayoutRes;
@@ -74,7 +75,6 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
int ivTorchId = getIvTorchId();
if(ivTorchId != 0){
ivTorch = mRootView.findViewById(ivTorchId);
ivTorch.setVisibility(View.INVISIBLE);
}
initCaptureHelper();
}
@@ -185,7 +185,7 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
* @return 返回true表示拦截将不自动执行后续逻辑为false表示不拦截默认不拦截
*/
@Override
public boolean onResultCallback(String result) {
public boolean onResultCallback(Result result) {
return false;
}

View File

@@ -26,7 +26,6 @@ import java.util.Map;
*/
public class CaptureHandler extends Handler implements ResultPointCallback {
private static final String TAG = CaptureHandler.class.getSimpleName();
private final OnCaptureListener onCaptureListener;
private final DecodeThread decodeThread;
@@ -155,27 +154,13 @@ public class CaptureHandler extends Handler implements ResultPointCallback {
*/
private ResultPoint transform(ResultPoint originPoint) {
Point screenPoint = cameraManager.getScreenResolution();
Point cameraPoint = cameraManager.getCameraResolution();
Point previewPoint = cameraManager.getPreviewSizeOnScreen();
float scaleX;
float scaleY;
float x;
float y;
if(screenPoint.x < screenPoint.y){
scaleX = 1.0f * screenPoint.x / cameraPoint.y;
scaleY = 1.0f * screenPoint.y / cameraPoint.x;
x = originPoint.getX() * scaleX - Math.max(screenPoint.x,cameraPoint.y)/2;
y = originPoint.getY() * scaleY - Math.min(screenPoint.y,cameraPoint.x)/2;
}else{
scaleX = 1.0f * screenPoint.x / cameraPoint.x;
scaleY = 1.0f * screenPoint.y / cameraPoint.y;
x = originPoint.getX() * scaleX - Math.min(screenPoint.y,cameraPoint.y)/2;
y = originPoint.getY() * scaleY - Math.max(screenPoint.x,cameraPoint.x)/2;
}
float scaleX = 1.0f * screenPoint.x / previewPoint.x;
float scaleY = 1.0f * screenPoint.y / previewPoint.y;
float x = originPoint.getX() * scaleX - Math.min(screenPoint.y,previewPoint.y)/2;
float y = originPoint.getY() * scaleY - Math.max(screenPoint.x,previewPoint.x)/2;
return new ResultPoint(x,y);
}

View File

@@ -31,7 +31,6 @@ import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.Result;
import com.king.zxing.camera.CameraManager;
import com.king.zxing.camera.FrontLightMode;
import com.king.zxing.util.LogUtils;
import java.io.IOException;
@@ -153,6 +152,11 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
private boolean hasCameraFlash;
/**
* 是否启用光线传感器
*/
private boolean isAmbientLightEnabled = true;
/**
* use {@link #CaptureHelper(Fragment, SurfaceView, ViewfinderView, View)}
* @param fragment
@@ -233,7 +237,10 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
} else {
surfaceHolder.addCallback(this);
}
ambientLightManager.start(cameraManager);
if(isAmbientLightEnabled){
ambientLightManager.start(cameraManager);
}
}
@@ -244,7 +251,9 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
captureHandler = null;
}
inactivityTimer.onPause();
ambientLightManager.stop();
if(isAmbientLightEnabled) {
ambientLightManager.stop();
}
beepManager.close();
cameraManager.closeDriver();
if (!hasSurface) {
@@ -491,7 +500,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
* 重新启动扫码和解码器
*/
public void restartPreviewAndDecode(){
if(captureHandler!=null){
if(captureHandler != null){
captureHandler.restartPreviewAndDecode();
}
}
@@ -517,7 +526,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
final String text = result.getText();
if(isContinuousScan){
if(onCaptureCallback!=null){
onCaptureCallback.onResultCallback(text);
onCaptureCallback.onResultCallback(result);
}
if(isAutoRestartPreviewAndDecode){
restartPreviewAndDecode();
@@ -528,7 +537,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
if(isPlayBeep && captureHandler != null){//如果播放音效,则稍微延迟一点,给予播放音效时间
captureHandler.postDelayed(() -> {
//如果设置了回调并且onCallback返回为true则表示拦截
if(onCaptureCallback!=null && onCaptureCallback.onResultCallback(text)){
if(onCaptureCallback!=null && onCaptureCallback.onResultCallback(result)){
return;
}
Intent intent = new Intent();
@@ -541,7 +550,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
}
//如果设置了回调并且onCallback返回为true则表示拦截
if(onCaptureCallback!=null && onCaptureCallback.onResultCallback(text)){
if(onCaptureCallback!=null && onCaptureCallback.onResultCallback(result)){
return;
}
Intent intent = new Intent();
@@ -662,23 +671,6 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
return this;
}
/**
* 设置闪光灯模式。当设置模式为:{@link FrontLightMode#AUTO}时,如果满意默认的照度值范围,
* 可通过{@link #tooDarkLux(float)}和{@link #brightEnoughLux(float)}来自定义照度范围,
* 控制自动触发开启和关闭闪光灯。
* 当设置模式非{@link FrontLightMode#AUTO}时,传感器不会检测,则不使用手电筒
*
* @param mode 默认:{@link FrontLightMode#AUTO}
* @return
*/
public CaptureHelper frontLightMode(FrontLightMode mode) {
FrontLightMode.put(activity,mode);
if(ivTorch!=null && mode != FrontLightMode.AUTO){
ivTorch.setVisibility(View.INVISIBLE);
}
return this;
}
/**
* 设置光线太暗时,自动显示手电筒按钮
* @param tooDarkLux 默认:{@link AmbientLightManager#TOO_DARK_LUX}
@@ -798,6 +790,16 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
return this;
}
/**
* 是否启用光线传感器
* @param isAmbientLightEnabled
* @return
*/
public CaptureHelper ambientLightEnabled(boolean isAmbientLightEnabled){
this.isAmbientLightEnabled = isAmbientLightEnabled;
return this;
}
/**
* 设置扫码回调

View File

@@ -27,7 +27,6 @@ import android.os.Message;
import android.view.Display;
import android.view.WindowManager;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
@@ -148,16 +147,22 @@ final class DecodeHandler extends Handler {
long end = System.currentTimeMillis();
LogUtils.d("Found barcode in " + (end - start) + " ms");
BarcodeFormat barcodeFormat = rawResult.getBarcodeFormat();
if(handler!=null && handler.isSupportAutoZoom() && barcodeFormat == BarcodeFormat.QR_CODE){
if(handler.isSupportAutoZoom()){//是否支持自动放大
ResultPoint[] resultPoints = rawResult.getResultPoints();
if(resultPoints.length >= 3){
float distance1 = ResultPoint.distance(resultPoints[0],resultPoints[1]);
float distance2 = ResultPoint.distance(resultPoints[1],resultPoints[2]);
float distance3 = ResultPoint.distance(resultPoints[0],resultPoints[2]);
int maxDistance = (int)Math.max(Math.max(distance1,distance2),distance3);
if(handleAutoZoom(maxDistance,width)){
LogUtils.d("resultPoints:" +resultPoints.length);
final int length = resultPoints.length;
if(length >= 2){//超过两个点则计算距离
int ratio = 6;
int maxDistance = (int)ResultPoint.distance(resultPoints[0],resultPoints[1]);
if(length >= 3){
float distance2 = ResultPoint.distance(resultPoints[1],resultPoints[2]);
float distance3 = ResultPoint.distance(resultPoints[0],resultPoints[2]);
maxDistance = (int)Math.max(Math.max(maxDistance,distance2),distance3);
ratio = 5;
}
if(handleAutoZoom(maxDistance,width,ratio)){//根据点之间的最大距离
Message message = Message.obtain();
message.what = R.id.decode_succeeded;
message.obj = rawResult;
@@ -170,23 +175,19 @@ final class DecodeHandler extends Handler {
return;
}
}
}
if (handler != null) {
Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
if(handler.isReturnBitmap()){
Bundle bundle = new Bundle();
bundleThumbnail(source, bundle);
message.setData(bundle);
}
message.sendToTarget();
Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);
if(handler.isReturnBitmap()){
Bundle bundle = new Bundle();
bundleThumbnail(source, bundle);
message.setData(bundle);
}
message.sendToTarget();
} else {
if (handler != null) {
Message message = Message.obtain(handler, R.id.decode_failed);
message.sendToTarget();
}
Message message = Message.obtain(handler, R.id.decode_failed);
message.sendToTarget();
}
}
@@ -219,12 +220,12 @@ final class DecodeHandler extends Handler {
bundle.putFloat(DecodeThread.BARCODE_SCALED_FACTOR, (float) width / source.getWidth());
}
private boolean handleAutoZoom(int length,int width){
private boolean handleAutoZoom(int length,int width,int ratio){
if(lastZoomTime > System.currentTimeMillis() - 1000){
return true;
return false;
}
if(length < width/ 5){
if(length < width / ratio){
Camera camera = cameraManager.getOpenCamera().getCamera();
if(camera!=null){

View File

@@ -35,8 +35,6 @@ import java.util.concurrent.RejectedExecutionException;
*/
final class InactivityTimer {
private static final String TAG = InactivityTimer.class.getSimpleName();
private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L;
private final Activity activity;
@@ -106,7 +104,7 @@ final class InactivityTimer {
// 0 indicates that we're on battery
InactivityTimer inactivityTimer = weakReference.get();
if(inactivityTimer!=null){
if(inactivityTimer != null){
boolean onBatteryNow = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) <= 0;
if (onBatteryNow) {
inactivityTimer.onActivity();

View File

@@ -1,6 +1,7 @@
package com.king.zxing;
import com.google.zxing.Result;
/**
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
@@ -12,5 +13,5 @@ public interface OnCaptureCallback {
* @param result 扫码结果
* @return 返回true表示拦截将不自动执行后续逻辑为false表示不拦截
*/
boolean onResultCallback(String result);
boolean onResultCallback(Result result);
}

View File

@@ -52,7 +52,7 @@ public final class ViewfinderView extends View {
private static final int CURRENT_POINT_OPACITY = 0xA0;
private static final int MAX_RESULT_POINTS = 20;
private static final int POINT_SIZE = 20;
private static final int POINT_SIZE = 30;
/**
* 画笔
@@ -176,7 +176,7 @@ public final class ViewfinderView extends View {
private int frameLineWidth;
/**
* 扫描动画延迟间隔时间 默认15毫秒
* 扫描动画延迟间隔时间 默认20毫秒
*/
private int scannerAnimationDelay;
@@ -274,7 +274,7 @@ public final class ViewfinderView extends View {
scannerLineMoveDistance = (int)array.getDimension(R.styleable.ViewfinderView_scannerLineMoveDistance,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,2,getResources().getDisplayMetrics()));
scannerLineHeight = (int)array.getDimension(R.styleable.ViewfinderView_scannerLineHeight,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,5,getResources().getDisplayMetrics()));
frameLineWidth = (int)array.getDimension(R.styleable.ViewfinderView_frameLineWidth,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics()));
scannerAnimationDelay = array.getInteger(R.styleable.ViewfinderView_scannerAnimationDelay,15);
scannerAnimationDelay = array.getInteger(R.styleable.ViewfinderView_scannerAnimationDelay,20);
frameRatio = array.getFloat(R.styleable.ViewfinderView_frameRatio,0.625f);
array.recycle();

View File

@@ -42,7 +42,6 @@ final class CameraConfigurationManager {
private int cwNeededRotation;
private int cwRotationFromDisplayToCamera;
private Point screenResolution;
private Point cameraResolution;
private Point bestPreviewSize;
private Point previewSizeOnScreen;
@@ -81,6 +80,7 @@ final class CameraConfigurationManager {
throw new IllegalArgumentException("Bad rotation: " + displayRotation);
}
}
LogUtils.i("Display at: " + cwRotationFromNaturalToDisplay);
int cwRotationFromNaturalToCamera = camera.getOrientation();
@@ -92,19 +92,6 @@ final class CameraConfigurationManager {
LogUtils.i("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)) {
LogUtils.i("Overriding camera manually to " + overrideRotationString);
cwRotationFromNaturalToCamera = Integer.parseInt(overrideRotationString);
}
*/
cwRotationFromDisplayToCamera = (360 + cwRotationFromNaturalToCamera - cwRotationFromNaturalToDisplay) % 360;
LogUtils.i("Final display orientation: " + cwRotationFromDisplayToCamera);
@@ -116,32 +103,26 @@ final class CameraConfigurationManager {
}
LogUtils.i("Clockwise rotation from display to camera: " + cwNeededRotation);
Point theScreenResolution = new Point();
display.getSize(theScreenResolution);
screenResolution = theScreenResolution;
screenResolution = new Point();
display.getSize(screenResolution);
LogUtils.i("Screen resolution in current orientation: " + screenResolution);
cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
LogUtils.i("Camera resolution: " + cameraResolution);
bestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
LogUtils.i("Best available preview size: " + bestPreviewSize);
boolean isScreenPortrait = screenResolution.x < screenResolution.y;
boolean isPreviewSizePortrait = bestPreviewSize.x < bestPreviewSize.y;
if (isScreenPortrait == isPreviewSizePortrait) {
previewSizeOnScreen = bestPreviewSize;
} else {
if (isScreenPortrait) {
previewSizeOnScreen = new Point(bestPreviewSize.y, bestPreviewSize.x);
} else {
previewSizeOnScreen = bestPreviewSize;
}
LogUtils.i("Preview size on screen: " + previewSizeOnScreen);
}
void setDesiredCameraParameters(OpenCamera camera, boolean safeMode) {
Camera theCamera = camera.getCamera();
Camera.Parameters parameters = theCamera.getParameters();
if (parameters == null) {
LogUtils.w("Device error: no camera parameters are available. Proceeding without configuration.");
return;
@@ -159,7 +140,7 @@ final class CameraConfigurationManager {
parameters.setZoom(parameters.getMaxZoom() / 10);
}
initializeTorch(parameters, prefs, safeMode);
// initializeTorch(parameters, prefs, safeMode);
CameraConfigurationUtils.setFocus(
parameters,
@@ -189,9 +170,9 @@ final class CameraConfigurationManager {
}
parameters.setPreviewSize(bestPreviewSize.x, bestPreviewSize.y);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
theCamera.setParameters(parameters);
theCamera.cancelAutoFocus();
theCamera.setDisplayOrientation(cwRotationFromDisplayToCamera);
Camera.Parameters afterParameters = theCamera.getParameters();
@@ -202,6 +183,7 @@ final class CameraConfigurationManager {
bestPreviewSize.x = afterSize.width;
bestPreviewSize.y = afterSize.height;
}
}
Point getBestPreviewSize() {
@@ -212,10 +194,6 @@ final class CameraConfigurationManager {
return previewSizeOnScreen;
}
Point getCameraResolution() {
return cameraResolution;
}
Point getScreenResolution() {
return screenResolution;
}
@@ -243,17 +221,16 @@ final class CameraConfigurationManager {
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 initializeTorch(Camera.Parameters parameters, boolean safeMode) {
doSetTorch(parameters, false, safeMode);
}
private void doSetTorch(Camera.Parameters parameters, boolean newSetting, boolean safeMode) {
CameraConfigurationUtils.setTorch(parameters, newSetting);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
if (!safeMode && !prefs.getBoolean(Preferences.KEY_DISABLE_EXPOSURE, true)) {
CameraConfigurationUtils.setBestExposure(parameters, newSetting);
}
// SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// if (!safeMode && !prefs.getBoolean(Preferences.KEY_DISABLE_EXPOSURE, true)) {
// CameraConfigurationUtils.setBestExposure(parameters, newSetting);
// }
}
}

View File

@@ -26,6 +26,7 @@ import com.king.zxing.util.LogUtils;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
@@ -269,89 +270,56 @@ public final class CameraConfigurationUtils {
}
}
/**
* 预览尺寸与给定的宽高尺寸比较器。首先比较宽高的比例,在宽高比相同的情况下,根据宽和高的最小差进行比较。
*/
private static class SizeComparator implements Comparator<Camera.Size> {
private final int width;
private final int height;
private final float ratio;
SizeComparator(int width, int height) {
//不管横屏还是竖屏parameters.getSupportedPreviewSizes()的size.width 始终大于或等于 size.height
if (width < height) {
this.width = height;
this.height = width;
} else {
this.width = width;
this.height = height;
}
this.ratio = (float) this.height / this.width;
}
@Override
public int compare(Camera.Size size1, Camera.Size size2) {
int width1 = size1.width;
int height1 = size1.height;
int width2 = size2.width;
int height2 = size2.height;
float ratio1 = Math.abs((float) height1 / width1 - ratio);
float ratio2 = Math.abs((float) height2 / width2 - ratio);
int result = Float.compare(ratio1, ratio2);
if (result != 0) {
return result;
} else {
int minGap1 = Math.abs(width - width1) + Math.abs(height - height1);
int minGap2 = Math.abs(width - width2) + Math.abs(height - height2);
return minGap1 - minGap2;
}
}
}
/**
* 在Camera支持的预览尺寸中找到最佳的预览尺寸
* @param parameters
* @param screenResolution
* @return
*/
public static Point findBestPreviewSizeValue(Camera.Parameters parameters,final Point screenResolution) {
List<Camera.Size> rawSupportedSizes = parameters.getSupportedPreviewSizes();
if (rawSupportedSizes == null) {
LogUtils.w( "Device returned no supported preview sizes; using default");
Camera.Size defaultSize = parameters.getPreviewSize();
if (defaultSize == null) {
throw new IllegalStateException("Parameters contained no preview size!");
}
return new Point(defaultSize.width, defaultSize.height);
}
if (LogUtils.isShowLog()) {
StringBuilder previewSizesString = new StringBuilder();
for (Camera.Size size : rawSupportedSizes) {
previewSizesString.append(size.width).append('x').append(size.height).append(' ');
}
LogUtils.d( "Supported preview sizes: " + previewSizesString);
}
double screenAspectRatio;
if(screenResolution.x < screenResolution.y){
screenAspectRatio = screenResolution.x / (double) screenResolution.y;
}else{
screenAspectRatio = screenResolution.y / (double) screenResolution.x;
}
LogUtils.d( "screenAspectRatio: " + screenAspectRatio);
// Find a suitable size, with max resolution
int maxResolution = 0;
Camera.Size maxResPreviewSize = null;
for (Camera.Size size : rawSupportedSizes) {
int realWidth = size.width;
int realHeight = size.height;
int resolution = realWidth * realHeight;
if (resolution < MIN_PREVIEW_PIXELS) {
continue;
}
boolean isCandidatePortrait = realWidth < realHeight;
int maybeFlippedWidth = isCandidatePortrait ? realWidth: realHeight ;
int maybeFlippedHeight = isCandidatePortrait ? realHeight : realWidth;
LogUtils.d( String.format("maybeFlipped:%d * %d",maybeFlippedWidth,maybeFlippedHeight));
double aspectRatio = maybeFlippedWidth / (double) maybeFlippedHeight;
LogUtils.d( "aspectRatio: " + aspectRatio);
double distortion = Math.abs(aspectRatio - screenAspectRatio);
LogUtils.d( "distortion: " + distortion);
if (distortion > MAX_ASPECT_DISTORTION) {
continue;
}
if (maybeFlippedWidth == screenResolution.x && maybeFlippedHeight == screenResolution.y) {
Point exactPoint = new Point(realWidth, realHeight);
LogUtils.d( "Found preview size exactly matching screen size: " + exactPoint);
return exactPoint;
}
// Resolution is suitable; record the one with max resolution
if (resolution > maxResolution) {
maxResolution = resolution;
maxResPreviewSize = size;
}
}
// 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 (maxResPreviewSize != null) {
Point largestSize = new Point(maxResPreviewSize.width, maxResPreviewSize.height);
LogUtils.d( "Using largest suitable preview size: " + largestSize);
return largestSize;
}
// If there is nothing at all suitable, return current preview size
Camera.Size defaultPreview = parameters.getPreviewSize();
if (defaultPreview == null) {
throw new IllegalStateException("Parameters contained no preview size!");
}
Point defaultSize = new Point(defaultPreview.width, defaultPreview.height);
LogUtils.d( "No suitable preview sizes, using default: " + defaultSize);
return defaultSize;
List<Camera.Size> preList = parameters.getSupportedPreviewSizes();
Collections.sort(preList, new SizeComparator(screenResolution.x, screenResolution.y));
Camera.Size size = preList.get(0);
return new Point(size.width,size.height);
}
private static String findSettableValue(String name,

View File

@@ -168,7 +168,7 @@ public final class CameraManager {
if (theCamera != null && !previewing) {
theCamera.getCamera().startPreview();
previewing = true;
autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
// autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
}
}
@@ -204,7 +204,7 @@ public final class CameraManager {
configManager.setTorch(theCamera.getCamera(), newSetting);
if (wasAutoFocusManager) {
autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
autoFocusManager.start();
// autoFocusManager.start();
}
if(onTorchListener!=null){
@@ -225,6 +225,7 @@ public final class CameraManager {
* @param message The what field of the message to be sent.
*/
public synchronized void requestPreviewFrame(Handler handler, int message) {
LogUtils.d("requestPreviewFrame");
OpenCamera theCamera = camera;
if (theCamera != null && previewing) {
previewCallback.setHandler(handler, message);
@@ -244,7 +245,7 @@ public final class CameraManager {
if (camera == null) {
return null;
}
Point point = configManager.getCameraResolution();
Point point = configManager.getBestPreviewSize();
if (point == null) {
// Called early, before init even finished
return null;
@@ -281,22 +282,17 @@ public final class CameraManager {
return null;
}
Rect rect = new Rect(framingRect);
Point cameraResolution = configManager.getCameraResolution();
Point preViewResolution = configManager.getPreviewSizeOnScreen();
Point screenResolution = configManager.getScreenResolution();
if (cameraResolution == null || screenResolution == null) {
if (preViewResolution == null || screenResolution == null) {
// Called early, before init even finished
return null;
}
// rect.left = rect.left * cameraResolution.x / screenResolution.x;
// rect.right = rect.right * cameraResolution.x / screenResolution.x;
// rect.top = rect.top * cameraResolution.y / screenResolution.y;
// rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
rect.left = rect.left * cameraResolution.y / screenResolution.x;
rect.right = rect.right * cameraResolution.y / screenResolution.x;
rect.top = rect.top * cameraResolution.x / screenResolution.y;
rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
rect.left = rect.left * preViewResolution.x / screenResolution.x;
rect.right = rect.right * preViewResolution.x / screenResolution.x;
rect.top = rect.top * preViewResolution.y / screenResolution.y;
rect.bottom = rect.bottom * preViewResolution.y / screenResolution.y;
framingRectInPreview = rect;
@@ -321,8 +317,12 @@ public final class CameraManager {
this.framingRectHorizontalOffset = framingRectHorizontalOffset;
}
public Point getCameraResolution() {
return configManager.getCameraResolution();
public Point getBestPreviewSize(){
return configManager.getBestPreviewSize();
}
public Point getPreviewSizeOnScreen() {
return configManager.getPreviewSizeOnScreen();
}
public Point getScreenResolution() {

View File

@@ -44,7 +44,7 @@ final class PreviewCallback implements Camera.PreviewCallback {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = configManager.getCameraResolution();
Point cameraResolution = configManager.getBestPreviewSize();
Handler thePreviewHandler = previewHandler;
if (cameraResolution != null && thePreviewHandler != null) {
Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,

View File

@@ -59,6 +59,7 @@ public final class OpenCameraInterface {
cameraId = 0;
while (cameraId < numCameras) {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, cameraInfo);
if (CameraFacing.values()[cameraInfo.facing] == CameraFacing.BACK) {
break;