@@ -36,8 +36,17 @@ import com.king.zxing.camera.FrontLightMode;
|
||||
*/
|
||||
final class AmbientLightManager implements SensorEventListener {
|
||||
|
||||
private static final float TOO_DARK_LUX = 45.0f;
|
||||
private static final float BRIGHT_ENOUGH_LUX = 450.0f;
|
||||
protected static final float TOO_DARK_LUX = 45.0f;
|
||||
protected static final float BRIGHT_ENOUGH_LUX = 100.0f;
|
||||
|
||||
/**
|
||||
* 光线太暗时,默认:照度45 lux
|
||||
*/
|
||||
private float tooDarkLux = TOO_DARK_LUX;
|
||||
/**
|
||||
* 光线足够亮时,默认:照度450 lux
|
||||
*/
|
||||
private float brightEnoughLux = BRIGHT_ENOUGH_LUX;
|
||||
|
||||
private final Context context;
|
||||
private CameraManager cameraManager;
|
||||
@@ -72,14 +81,22 @@ final class AmbientLightManager implements SensorEventListener {
|
||||
public void onSensorChanged(SensorEvent sensorEvent) {
|
||||
float ambientLightLux = sensorEvent.values[0];
|
||||
if (cameraManager != null) {
|
||||
if (ambientLightLux <= TOO_DARK_LUX) {
|
||||
cameraManager.setTorch(true);
|
||||
} else if (ambientLightLux >= BRIGHT_ENOUGH_LUX) {
|
||||
cameraManager.setTorch(false);
|
||||
if (ambientLightLux <= tooDarkLux) {
|
||||
cameraManager.sensorChanged(true,ambientLightLux);
|
||||
} else if (ambientLightLux >= brightEnoughLux) {
|
||||
cameraManager.sensorChanged(false,ambientLightLux);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setTooDarkLux(float tooDarkLux){
|
||||
this.tooDarkLux = tooDarkLux;
|
||||
}
|
||||
|
||||
public void setBrightEnoughLux(float brightEnoughLux){
|
||||
this.brightEnoughLux = brightEnoughLux;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// do nothing
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
|
||||
import com.king.zxing.camera.CameraManager;
|
||||
|
||||
@@ -31,6 +32,7 @@ public class CaptureActivity extends Activity implements OnCaptureCallback{
|
||||
|
||||
private SurfaceView surfaceView;
|
||||
private ViewfinderView viewfinderView;
|
||||
private View ivTorch;
|
||||
|
||||
private CaptureHelper mCaptureHelper;
|
||||
|
||||
@@ -50,7 +52,12 @@ public class CaptureActivity extends Activity implements OnCaptureCallback{
|
||||
public void initUI(){
|
||||
surfaceView = findViewById(getSurfaceViewId());
|
||||
viewfinderView = findViewById(getViewfinderViewId());
|
||||
mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView);
|
||||
int ivTorchId = getIvTorchId();
|
||||
if(ivTorchId != 0){
|
||||
ivTorch = findViewById(ivTorchId);
|
||||
ivTorch.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView,ivTorch);
|
||||
mCaptureHelper.setOnCaptureCallback(this);
|
||||
mCaptureHelper.onCreate();
|
||||
}
|
||||
@@ -73,7 +80,7 @@ public class CaptureActivity extends Activity implements OnCaptureCallback{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ViewfinderView} 的 id
|
||||
* {@link #viewfinderView} 的 ID
|
||||
* @return
|
||||
*/
|
||||
public int getViewfinderViewId(){
|
||||
@@ -82,13 +89,21 @@ public class CaptureActivity extends Activity implements OnCaptureCallback{
|
||||
|
||||
|
||||
/**
|
||||
* 预览界面{@link #surfaceView} 的id
|
||||
* 预览界面{@link #surfaceView} 的ID
|
||||
* @return
|
||||
*/
|
||||
public int getSurfaceViewId(){
|
||||
return R.id.surfaceView;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 {@link #ivTorch} 的ID
|
||||
* @return 默认返回{@code R.id.ivTorch}, 如果不需要手电筒按钮可以返回0
|
||||
*/
|
||||
public int getIvTorchId(){
|
||||
return R.id.ivTorch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link CaptureHelper}
|
||||
* @return {@link #mCaptureHelper}
|
||||
|
||||
@@ -37,13 +37,14 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
|
||||
|
||||
private SurfaceView surfaceView;
|
||||
private ViewfinderView viewfinderView;
|
||||
private View ivTorch;
|
||||
|
||||
private CaptureHelper mCaptureHelper;
|
||||
|
||||
public static CaptureFragment newInstance() {
|
||||
|
||||
Bundle args = new Bundle();
|
||||
|
||||
|
||||
CaptureFragment fragment = new CaptureFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
@@ -66,7 +67,12 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
|
||||
public void initUI(){
|
||||
surfaceView = mRootView.findViewById(getSurfaceViewId());
|
||||
viewfinderView = mRootView.findViewById(getViewfinderViewId());
|
||||
mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView);
|
||||
int ivTorchId = getIvTorchId();
|
||||
if(ivTorchId != 0){
|
||||
ivTorch = mRootView.findViewById(ivTorchId);
|
||||
ivTorch.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
mCaptureHelper = new CaptureHelper(this,surfaceView,viewfinderView,ivTorch);
|
||||
mCaptureHelper.setOnCaptureCallback(this);
|
||||
}
|
||||
|
||||
@@ -95,7 +101,6 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
|
||||
return R.id.viewfinderView;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 预览界面{@link #surfaceView} 的id
|
||||
* @return
|
||||
@@ -104,6 +109,14 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
|
||||
return R.id.surfaceView;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 {@link #ivTorch} 的ID
|
||||
* @return 默认返回{@code R.id.ivTorch}, 如果不需要手电筒按钮可以返回0
|
||||
*/
|
||||
public int getIvTorchId(){
|
||||
return R.id.ivTorch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link CaptureHelper}
|
||||
* @return {@link #mCaptureHelper}
|
||||
@@ -167,4 +180,4 @@ public class CaptureFragment extends Fragment implements OnCaptureCallback {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ package com.king.zxing;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.hardware.Camera;
|
||||
@@ -26,11 +27,13 @@ import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
|
||||
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 java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -61,6 +64,7 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
||||
private ViewfinderView viewfinderView;
|
||||
private SurfaceHolder surfaceHolder;
|
||||
private SurfaceHolder.Callback callback;
|
||||
private View ivTorch;
|
||||
|
||||
private Collection<BarcodeFormat> decodeFormats;
|
||||
private Map<DecodeHintType,Object> decodeHints;
|
||||
@@ -126,21 +130,58 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
||||
* 识别区域水平方向偏移量
|
||||
*/
|
||||
private int framingRectHorizontalOffset;
|
||||
|
||||
/**
|
||||
* 光线太暗,当光线亮度太暗,亮度低于此值时,显示手电筒按钮
|
||||
*/
|
||||
private float tooDarkLux = AmbientLightManager.TOO_DARK_LUX;
|
||||
/**
|
||||
* 光线足够明亮,当光线亮度足够明亮,亮度高于此值时,隐藏手电筒按钮
|
||||
*/
|
||||
private float brightEnoughLux = AmbientLightManager.BRIGHT_ENOUGH_LUX;
|
||||
/**
|
||||
* 扫码回调
|
||||
*/
|
||||
private OnCaptureCallback onCaptureCallback;
|
||||
|
||||
|
||||
/**
|
||||
* use {@link #CaptureHelper(Fragment, SurfaceView, ViewfinderView, View)}
|
||||
* @param fragment
|
||||
* @param surfaceView
|
||||
* @param viewfinderView
|
||||
*/
|
||||
@Deprecated
|
||||
public CaptureHelper(Fragment fragment, SurfaceView surfaceView, ViewfinderView viewfinderView){
|
||||
this(fragment.getActivity(),surfaceView,viewfinderView);
|
||||
|
||||
this(fragment,surfaceView,viewfinderView,null);
|
||||
}
|
||||
|
||||
public CaptureHelper(Fragment fragment, SurfaceView surfaceView, ViewfinderView viewfinderView,View ivTorch){
|
||||
this(fragment.getActivity(),surfaceView,viewfinderView,ivTorch);
|
||||
}
|
||||
|
||||
/**
|
||||
* use {@link #CaptureHelper(Activity, SurfaceView, ViewfinderView, View)}
|
||||
* @param activity
|
||||
* @param surfaceView
|
||||
* @param viewfinderView
|
||||
*/
|
||||
@Deprecated
|
||||
public CaptureHelper(Activity activity,SurfaceView surfaceView,ViewfinderView viewfinderView){
|
||||
this(activity,surfaceView,viewfinderView,null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param activity
|
||||
* @param surfaceView
|
||||
* @param viewfinderView
|
||||
* @param ivTorch
|
||||
*/
|
||||
public CaptureHelper(Activity activity,SurfaceView surfaceView,ViewfinderView viewfinderView,View ivTorch){
|
||||
this.activity = activity;
|
||||
this.viewfinderView = viewfinderView;
|
||||
this.ivTorch = ivTorch;
|
||||
surfaceHolder = surfaceView.getHolder();
|
||||
hasSurface = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -155,6 +196,22 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
||||
cameraManager.setFramingRectRatio(framingRectRatio);
|
||||
cameraManager.setFramingRectVerticalOffset(framingRectVerticalOffset);
|
||||
cameraManager.setFramingRectHorizontalOffset(framingRectHorizontalOffset);
|
||||
if(ivTorch !=null && activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)){
|
||||
ivTorch.setOnClickListener(v -> cameraManager.setTorch(!ivTorch.isSelected()));
|
||||
cameraManager.setOnSensorListener((torch, tooDark, ambientLightLux) -> {
|
||||
if(tooDark){
|
||||
if(ivTorch.getVisibility() != View.VISIBLE){
|
||||
ivTorch.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}else if(!torch){
|
||||
if(ivTorch.getVisibility() == View.VISIBLE){
|
||||
ivTorch.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
cameraManager.setOnTorchListener(torch -> ivTorch.setSelected(torch));
|
||||
|
||||
}
|
||||
callback = new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
@@ -186,6 +243,11 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
||||
//设置是否播放音效和震动
|
||||
beepManager.setPlayBeep(isPlayBeep);
|
||||
beepManager.setVibrate(isVibrate);
|
||||
|
||||
//设置闪光灯的太暗时和足够亮时的照度值
|
||||
ambientLightManager.setTooDarkLux(tooDarkLux);
|
||||
ambientLightManager.setBrightEnoughLux(brightEnoughLux);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -565,6 +627,49 @@ 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}
|
||||
* @return
|
||||
*/
|
||||
public CaptureHelper tooDarkLux(float tooDarkLux) {
|
||||
this.tooDarkLux = tooDarkLux;
|
||||
if(ambientLightManager != null){
|
||||
ambientLightManager.setTooDarkLux(tooDarkLux);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置光线足够明亮时,自动隐藏手电筒按钮
|
||||
* @param brightEnoughLux 默认:{@link AmbientLightManager#BRIGHT_ENOUGH_LUX}
|
||||
* @return
|
||||
*/
|
||||
public CaptureHelper brightEnoughLux(float brightEnoughLux) {
|
||||
this.brightEnoughLux = brightEnoughLux;
|
||||
if(ambientLightManager != null){
|
||||
ambientLightManager.setTooDarkLux(tooDarkLux);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置返回扫码原图
|
||||
* @param returnBitmap 默认为false,当返回true表示扫码就结果会返回扫码原图,相应的会增加性能消耗。
|
||||
@@ -691,4 +796,4 @@ public class CaptureHelper implements CaptureLifecycle,CaptureTouchEvent,Capture
|
||||
public InactivityTimer getInactivityTimer() {
|
||||
return inactivityTimer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,6 +72,11 @@ public final class CameraManager {
|
||||
*/
|
||||
private final PreviewCallback previewCallback;
|
||||
|
||||
private OnTorchListener onTorchListener;
|
||||
private OnSensorListener onSensorListener;
|
||||
|
||||
private boolean isTorch;
|
||||
|
||||
public CameraManager(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.configManager = new CameraConfigurationManager(context);
|
||||
@@ -192,14 +197,22 @@ public final class CameraManager {
|
||||
autoFocusManager.stop();
|
||||
autoFocusManager = null;
|
||||
}
|
||||
this.isTorch = newSetting;
|
||||
configManager.setTorch(theCamera.getCamera(), newSetting);
|
||||
if (wasAutoFocusManager) {
|
||||
autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
|
||||
autoFocusManager.start();
|
||||
}
|
||||
|
||||
if(onTorchListener!=null){
|
||||
onTorchListener.onTorchChanged(newSetting);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A single preview frame will be returned to the handler supplied. The data will arrive as byte[]
|
||||
* in the message.obj field, with width and height encoded as message.arg1 and message.arg2,
|
||||
@@ -376,4 +389,49 @@ public final class CameraManager {
|
||||
size, size, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供闪光灯监听
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnTorchListener(OnTorchListener listener){
|
||||
this.onTorchListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 传感器光线照度监听
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnSensorListener(OnSensorListener listener){
|
||||
this.onSensorListener = listener;
|
||||
}
|
||||
|
||||
public void sensorChanged(boolean tooDark,float ambientLightLux){
|
||||
if(onSensorListener!=null){
|
||||
onSensorListener.onSensorChanged(isTorch,tooDark,ambientLightLux);
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnTorchListener{
|
||||
/**
|
||||
* 当闪光灯状态改变时触发
|
||||
* @param torch true表示开启、false表示关闭
|
||||
*/
|
||||
void onTorchChanged(boolean torch);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 传感器灯光亮度监听
|
||||
*/
|
||||
public interface OnSensorListener{
|
||||
/**
|
||||
*
|
||||
* @param torch 闪光灯是否开启
|
||||
* @param tooDark 传感器检测到的光线亮度,是否太暗
|
||||
* @param ambientLightLux 光线照度
|
||||
*/
|
||||
void onSensorChanged(boolean torch,boolean tooDark,float ambientLightLux);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -16,7 +16,9 @@ package com.king.zxing.camera;
|
||||
*/
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.king.zxing.Preferences;
|
||||
|
||||
@@ -33,11 +35,16 @@ public enum FrontLightMode {
|
||||
OFF;
|
||||
|
||||
private static FrontLightMode parse(String modeString) {
|
||||
return modeString == null ? OFF : valueOf(modeString);
|
||||
return modeString == null ? AUTO : valueOf(modeString);
|
||||
}
|
||||
|
||||
public static FrontLightMode readPref(SharedPreferences sharedPrefs) {
|
||||
return parse(sharedPrefs.getString(Preferences.KEY_FRONT_LIGHT_MODE, OFF.toString()));
|
||||
return parse(sharedPrefs.getString(Preferences.KEY_FRONT_LIGHT_MODE, AUTO.toString()));
|
||||
}
|
||||
|
||||
public static void put(Context context, FrontLightMode mode) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
prefs.edit().putString(Preferences.KEY_FRONT_LIGHT_MODE, mode.toString()).commit();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.FloatRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
@@ -51,7 +52,7 @@ import java.util.Vector;
|
||||
/**
|
||||
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
*/
|
||||
public class CodeUtils {
|
||||
public final class CodeUtils {
|
||||
|
||||
private CodeUtils(){
|
||||
throw new AssertionError();
|
||||
@@ -59,8 +60,8 @@ public class CodeUtils {
|
||||
|
||||
/**
|
||||
* 生成二维码
|
||||
* @param content
|
||||
* @param heightPix
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(String content, int heightPix) {
|
||||
@@ -68,13 +69,25 @@ public class CodeUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码
|
||||
* @param content
|
||||
* @param heightPix
|
||||
* @param logo
|
||||
* 生成我二维码
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @param logo logo大小默认占二维码的20%
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo) {
|
||||
return createQRCode(content,heightPix,logo,0.2f);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @param logo 二维码中间的logo
|
||||
* @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo,@FloatRange(from = 0.0f,to = 1.0f)float ratio) {
|
||||
//配置参数
|
||||
Map<EncodeHintType, Object> hints = new HashMap<>();
|
||||
hints.put( EncodeHintType.CHARACTER_SET, "utf-8");
|
||||
@@ -82,18 +95,19 @@ public class CodeUtils {
|
||||
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
|
||||
//设置空白边距的宽度
|
||||
hints.put(EncodeHintType.MARGIN, 1); //default is 4
|
||||
return createQRCode(content,heightPix,logo,hints);
|
||||
return createQRCode(content,heightPix,logo,ratio,hints);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码
|
||||
* @param content
|
||||
* @param heightPix
|
||||
* @param logo
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @param logo 二维码中间的logo
|
||||
* @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||
* @param hints
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo,Map<EncodeHintType,?> hints) {
|
||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo,@FloatRange(from = 0.0f,to = 1.0f)float ratio,Map<EncodeHintType,?> hints) {
|
||||
try {
|
||||
|
||||
// 图像数据转换,使用了矩阵转换
|
||||
@@ -116,7 +130,7 @@ public class CodeUtils {
|
||||
bitmap.setPixels(pixels, 0, heightPix, 0, 0, heightPix, heightPix);
|
||||
|
||||
if (logo != null) {
|
||||
bitmap = addLogo(bitmap, logo);
|
||||
bitmap = addLogo(bitmap, logo,ratio);
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
@@ -129,8 +143,12 @@ public class CodeUtils {
|
||||
|
||||
/**
|
||||
* 在二维码中间添加Logo图案
|
||||
* @param src
|
||||
* @param logo
|
||||
* @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||
* @return
|
||||
*/
|
||||
private static Bitmap addLogo(Bitmap src, Bitmap logo) {
|
||||
private static Bitmap addLogo(Bitmap src, Bitmap logo,@FloatRange(from = 0.0f,to = 1.0f) float ratio) {
|
||||
if (src == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -153,8 +171,8 @@ public class CodeUtils {
|
||||
return src;
|
||||
}
|
||||
|
||||
//logo大小为二维码整体大小的1/6
|
||||
float scaleFactor = srcWidth * 1.0f / 6 / logoWidth;
|
||||
//logo大小为二维码整体大小
|
||||
float scaleFactor = srcWidth * ratio / logoWidth;
|
||||
Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
|
||||
try {
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
@@ -255,7 +273,7 @@ public class CodeUtils {
|
||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||
try {
|
||||
result = reader.decodeWithState(bitmap);
|
||||
} catch (Exception e) {//解析失败则通过GlobalHistogramBinarizer 再试一次
|
||||
} catch (Exception e) {//解析失败时则通过GlobalHistogramBinarizer 再试一次
|
||||
BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
|
||||
try {
|
||||
result = reader.decodeWithState(bitmap1);
|
||||
@@ -290,7 +308,7 @@ public class CodeUtils {
|
||||
int h = newOpts.outHeight;
|
||||
float width = 800f;
|
||||
float height = 480f;
|
||||
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
|
||||
// 缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
|
||||
int be = 1;// be=1表示不缩放
|
||||
if (w > h && w > width) {// 如果宽度大的话根据宽度固定大小缩放
|
||||
be = (int) (newOpts.outWidth / width);
|
||||
@@ -451,4 +469,4 @@ public class CodeUtils {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user