1、支持连续扫码
2、支持横屏扫码(主要为了支持Pad)
This commit is contained in:
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
14
README.md
14
README.md
@@ -40,17 +40,17 @@ ZXingLite for Android 是ZXing的精简版,基于ZXing库优化扫码和生成
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.king.zxing</groupId>
|
<groupId>com.king.zxing</groupId>
|
||||||
<artifactId>zxing-lite</artifactId>
|
<artifactId>zxing-lite</artifactId>
|
||||||
<version>1.0.5</version>
|
<version>1.0.6</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
### Gradle:
|
### Gradle:
|
||||||
```gradle
|
```gradle
|
||||||
implementation 'com.king.zxing:zxing-lite:1.0.5'
|
implementation 'com.king.zxing:zxing-lite:1.0.6'
|
||||||
```
|
```
|
||||||
### Lvy:
|
### Lvy:
|
||||||
```lvy
|
```lvy
|
||||||
<dependency org='com.king.zxing' name='zxing-lite' rev='1.0.5'>
|
<dependency org='com.king.zxing' name='zxing-lite' rev='1.0.6'>
|
||||||
<artifact name='$AID' ext='pom'></artifact>
|
<artifact name='$AID' ext='pom'></artifact>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
@@ -99,6 +99,14 @@ api 'com.google.zxing:core:3.3.3'
|
|||||||
|
|
||||||
更多使用详情,请查看[app](app)中的源码使用示例
|
更多使用详情,请查看[app](app)中的源码使用示例
|
||||||
|
|
||||||
|
## 版本记录
|
||||||
|
#### v1.0.6:2019-1-16
|
||||||
|
* 支持连续扫码
|
||||||
|
* 支持横屏扫码(主要为了支持Pad)
|
||||||
|
|
||||||
|
#### v1.0.5:2018-12-29
|
||||||
|
* 支持自定义扫码框宽高
|
||||||
|
|
||||||
## 关于我
|
## 关于我
|
||||||
Name: <a title="关于作者" href="https://about.me/jenly1314" target="_blank">Jenly</a>
|
Name: <a title="关于作者" href="https://about.me/jenly1314" target="_blank">Jenly</a>
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.support.v7.widget.Toolbar;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.google.zxing.Result;
|
||||||
import com.king.zxing.CaptureActivity;
|
import com.king.zxing.CaptureActivity;
|
||||||
import com.king.zxing.app.util.StatusBarUtils;
|
import com.king.zxing.app.util.StatusBarUtils;
|
||||||
|
|
||||||
@@ -46,6 +47,9 @@ public class CustomCaptureActivity extends CaptureActivity {
|
|||||||
getBeepManager().setVibrate(true);
|
getBeepManager().setVibrate(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭闪光灯(手电筒)
|
||||||
|
*/
|
||||||
private void offFlash(){
|
private void offFlash(){
|
||||||
Camera camera = getCameraManager().getOpenCamera().getCamera();
|
Camera camera = getCameraManager().getOpenCamera().getCamera();
|
||||||
Camera.Parameters parameters = camera.getParameters();
|
Camera.Parameters parameters = camera.getParameters();
|
||||||
@@ -53,6 +57,9 @@ public class CustomCaptureActivity extends CaptureActivity {
|
|||||||
camera.setParameters(parameters);
|
camera.setParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启闪光灯(手电筒)
|
||||||
|
*/
|
||||||
public void openFlash(){
|
public void openFlash(){
|
||||||
Camera camera = getCameraManager().getOpenCamera().getCamera();
|
Camera camera = getCameraManager().getOpenCamera().getCamera();
|
||||||
Camera.Parameters parameters = camera.getParameters();
|
Camera.Parameters parameters = camera.getParameters();
|
||||||
@@ -60,6 +67,34 @@ public class CustomCaptureActivity extends CaptureActivity {
|
|||||||
camera.setParameters(parameters);
|
camera.setParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接收扫码结果,想支持连扫时,可将{@link #isContinuousScan()}返回为{@code true}并重写此方法
|
||||||
|
* 如果{@link #isContinuousScan()}支持连扫,则默认重启扫码和解码器;当连扫逻辑太复杂时,
|
||||||
|
* 请将{@link #isAutoRestartPreviewAndDecode()}返回为{@code false},并手动调用{@link #restartPreviewAndDecode()}
|
||||||
|
* @param result 扫码结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onResult(Result result) {
|
||||||
|
super.onResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否连续扫码,如果想支持连续扫码,则将此方法返回{@code true}并重写{@link #onResult(Result)}
|
||||||
|
* @return 默认返回 false
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isContinuousScan() {
|
||||||
|
return super.isContinuousScan();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否自动重启扫码和解码器,当支持连扫时才起作用。
|
||||||
|
* @return 默认返回 true
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isAutoRestartPreviewAndDecode() {
|
||||||
|
return super.isAutoRestartPreviewAndDecode();
|
||||||
|
}
|
||||||
|
|
||||||
private void clickFlash(View v){
|
private void clickFlash(View v){
|
||||||
if(v.isSelected()){
|
if(v.isSelected()){
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import android.view.SurfaceView;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.DecodeHintType;
|
import com.google.zxing.DecodeHintType;
|
||||||
@@ -178,12 +179,6 @@ public class CaptureActivity extends Activity implements SurfaceHolder.Callback
|
|||||||
handler = null;
|
handler = null;
|
||||||
lastResult = null;
|
lastResult = null;
|
||||||
|
|
||||||
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
|
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
|
||||||
} else {
|
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
resetStatusView();
|
resetStatusView();
|
||||||
|
|
||||||
|
|
||||||
@@ -443,6 +438,50 @@ public class CaptureActivity extends Activity implements SurfaceHolder.Callback
|
|||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新启动扫码和解码器
|
||||||
|
*/
|
||||||
|
public void restartPreviewAndDecode(){
|
||||||
|
if(handler!=null){
|
||||||
|
handler.restartPreviewAndDecode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接收扫码结果,想支持连扫时,可将{@link #isContinuousScan()}返回为{@code true}并重写此方法
|
||||||
|
* 如果{@link #isContinuousScan()}支持连扫,则默认重启扫码和解码器;当连扫逻辑太复杂时,
|
||||||
|
* 请将{@link #isAutoRestartPreviewAndDecode()}返回为{@code false},并手动调用{@link #restartPreviewAndDecode()}
|
||||||
|
* @param result 扫码结果
|
||||||
|
*/
|
||||||
|
public void onResult(Result result){
|
||||||
|
if(isContinuousScan()){
|
||||||
|
if(isAutoRestartPreviewAndDecode()){
|
||||||
|
restartPreviewAndDecode();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra(KEY_RESULT,result.getText());
|
||||||
|
setResult(RESULT_OK,intent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否连续扫码,如果想支持连续扫码,则将此方法返回{@code true}并重写{@link #onResult(Result)}
|
||||||
|
* @return 默认返回 false
|
||||||
|
*/
|
||||||
|
public boolean isContinuousScan(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否自动重启扫码和解码器,当支持连扫时才起作用。
|
||||||
|
* @return 默认返回 true
|
||||||
|
*/
|
||||||
|
public boolean isAutoRestartPreviewAndDecode(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A valid barcode has been found, so give an indication of success and show the results.
|
* A valid barcode has been found, so give an indication of success and show the results.
|
||||||
*
|
*
|
||||||
@@ -456,11 +495,9 @@ public class CaptureActivity extends Activity implements SurfaceHolder.Callback
|
|||||||
if(isBeepSoundAndVibrate()){
|
if(isBeepSoundAndVibrate()){
|
||||||
beepManager.playBeepSoundAndVibrate();
|
beepManager.playBeepSoundAndVibrate();
|
||||||
}
|
}
|
||||||
String resultString = rawResult.getText();
|
|
||||||
Intent intent = new Intent();
|
onResult(rawResult);
|
||||||
intent.putExtra(KEY_RESULT,resultString);
|
|
||||||
setResult(RESULT_OK,intent);
|
|
||||||
finish();
|
|
||||||
|
|
||||||
|
|
||||||
// ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);
|
// ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ public final class CaptureActivityHandler extends Handler {
|
|||||||
removeMessages(R.id.decode_failed);
|
removeMessages(R.id.decode_failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restartPreviewAndDecode() {
|
public void restartPreviewAndDecode() {
|
||||||
if (state == State.SUCCESS) {
|
if (state == State.SUCCESS) {
|
||||||
state = State.PREVIEW;
|
state = State.PREVIEW;
|
||||||
cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
|
cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
|
||||||
|
|||||||
@@ -16,20 +16,26 @@ package com.king.zxing;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import com.google.zxing.BinaryBitmap;
|
import com.google.zxing.BinaryBitmap;
|
||||||
import com.google.zxing.DecodeHintType;
|
import com.google.zxing.DecodeHintType;
|
||||||
import com.google.zxing.MultiFormatReader;
|
import com.google.zxing.MultiFormatReader;
|
||||||
|
import com.google.zxing.NotFoundException;
|
||||||
import com.google.zxing.PlanarYUVLuminanceSource;
|
import com.google.zxing.PlanarYUVLuminanceSource;
|
||||||
import com.google.zxing.ReaderException;
|
import com.google.zxing.ReaderException;
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
|
import com.google.zxing.common.GlobalHistogramBinarizer;
|
||||||
import com.google.zxing.common.HybridBinarizer;
|
import com.google.zxing.common.HybridBinarizer;
|
||||||
|
|
||||||
|
import android.graphics.Point;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -54,7 +60,7 @@ final class DecodeHandler extends Handler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (message.what == R.id.decode) {
|
if (message.what == R.id.decode) {
|
||||||
decode((byte[]) message.obj, message.arg1, message.arg2);
|
decode((byte[]) message.obj, message.arg1, message.arg2,isScreenPortrait());
|
||||||
|
|
||||||
} else if (message.what == R.id.quit) {
|
} else if (message.what == R.id.quit) {
|
||||||
running = false;
|
running = false;
|
||||||
@@ -63,6 +69,14 @@ final class DecodeHandler extends Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isScreenPortrait(){
|
||||||
|
WindowManager manager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
|
||||||
|
Display display = manager.getDefaultDisplay();
|
||||||
|
Point screenResolution = new Point();
|
||||||
|
display.getSize(screenResolution);
|
||||||
|
return screenResolution.x < screenResolution.y;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
|
* Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
|
||||||
* reuse the same reader objects from one decode to the next.
|
* reuse the same reader objects from one decode to the next.
|
||||||
@@ -71,24 +85,34 @@ final class DecodeHandler extends Handler {
|
|||||||
* @param width The width of the preview frame.
|
* @param width The width of the preview frame.
|
||||||
* @param height The height of the preview frame.
|
* @param height The height of the preview frame.
|
||||||
*/
|
*/
|
||||||
private void decode(byte[] data, int width, int height) {
|
private void decode(byte[] data, int width, int height,boolean isScreenPortrait) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Result rawResult = null;
|
Result rawResult = null;
|
||||||
byte[] rotatedData = new byte[data.length];
|
PlanarYUVLuminanceSource source;
|
||||||
for (int y = 0; y < height; y++) {
|
if(isScreenPortrait){
|
||||||
for (int x = 0; x < width; x++)
|
byte[] rotatedData = new byte[data.length];
|
||||||
rotatedData[x * height + height - y - 1] = data[x + y * width];
|
for (int y = 0; y < height; y++) {
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
rotatedData[x * height + height - y - 1] = data[x + y * width];
|
||||||
|
}
|
||||||
|
int tmp = width;
|
||||||
|
width = height;
|
||||||
|
height = tmp;
|
||||||
|
source = activity.getCameraManager().buildLuminanceSource(rotatedData, width, height);
|
||||||
|
}else{
|
||||||
|
source = activity.getCameraManager().buildLuminanceSource(data, width, height);
|
||||||
}
|
}
|
||||||
int tmp = width;
|
|
||||||
width = height;
|
|
||||||
height = tmp;
|
|
||||||
PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(rotatedData, width, height);
|
|
||||||
if (source != null) {
|
if (source != null) {
|
||||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||||
try {
|
try {
|
||||||
rawResult = multiFormatReader.decodeWithState(bitmap);
|
rawResult = multiFormatReader.decodeWithState(bitmap);
|
||||||
} catch (ReaderException re) {
|
} catch (Exception e) {
|
||||||
// continue
|
BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
|
||||||
|
try {
|
||||||
|
rawResult = multiFormatReader.decode(bitmap1);
|
||||||
|
} catch (NotFoundException ne) {
|
||||||
|
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
multiFormatReader.reset();
|
multiFormatReader.reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,8 +108,7 @@ final class CameraConfigurationManager {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cwRotationFromDisplayToCamera =
|
cwRotationFromDisplayToCamera = (360 + cwRotationFromNaturalToCamera - cwRotationFromNaturalToDisplay) % 360;
|
||||||
(360 + cwRotationFromNaturalToCamera - cwRotationFromNaturalToDisplay) % 360;
|
|
||||||
Log.i(TAG, "Final display orientation: " + cwRotationFromDisplayToCamera);
|
Log.i(TAG, "Final display orientation: " + cwRotationFromDisplayToCamera);
|
||||||
if (camera.getFacing() == CameraFacing.FRONT) {
|
if (camera.getFacing() == CameraFacing.FRONT) {
|
||||||
Log.i(TAG, "Compensating rotation for front camera");
|
Log.i(TAG, "Compensating rotation for front camera");
|
||||||
@@ -162,7 +161,6 @@ final class CameraConfigurationManager {
|
|||||||
parameters.setZoom(parameters.getMaxZoom() / 10);
|
parameters.setZoom(parameters.getMaxZoom() / 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
theCamera.setDisplayOrientation(90);
|
|
||||||
theCamera.setParameters(parameters);
|
theCamera.setParameters(parameters);
|
||||||
|
|
||||||
initializeTorch(parameters, prefs, safeMode);
|
initializeTorch(parameters, prefs, safeMode);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public final class CameraConfigurationUtils {
|
|||||||
private static final int MIN_PREVIEW_PIXELS = 480 * 320; // normal screen
|
private static final int MIN_PREVIEW_PIXELS = 480 * 320; // normal screen
|
||||||
private static final float MAX_EXPOSURE_COMPENSATION = 1.5f;
|
private static final float MAX_EXPOSURE_COMPENSATION = 1.5f;
|
||||||
private static final float MIN_EXPOSURE_COMPENSATION = 0.0f;
|
private static final float MIN_EXPOSURE_COMPENSATION = 0.0f;
|
||||||
private static final double MAX_ASPECT_DISTORTION = 0.10;
|
private static final double MAX_ASPECT_DISTORTION = 0.05;
|
||||||
private static final int MIN_FPS = 10;
|
private static final int MIN_FPS = 10;
|
||||||
private static final int MAX_FPS = 20;
|
private static final int MAX_FPS = 20;
|
||||||
private static final int AREA_PER_1000 = 400;
|
private static final int AREA_PER_1000 = 400;
|
||||||
@@ -292,10 +292,16 @@ public final class CameraConfigurationUtils {
|
|||||||
Log.i(TAG, "Supported preview sizes: " + previewSizesString);
|
Log.i(TAG, "Supported preview sizes: " + previewSizesString);
|
||||||
}
|
}
|
||||||
|
|
||||||
double screenAspectRatio = screenResolution.x / (double) screenResolution.y;
|
double screenAspectRatio;
|
||||||
|
if(screenResolution.x < screenResolution.y){
|
||||||
|
screenAspectRatio = screenResolution.x / (double) screenResolution.y;
|
||||||
|
}else{
|
||||||
|
screenAspectRatio = screenResolution.y / (double) screenResolution.x;
|
||||||
|
}
|
||||||
Log.i(TAG, "screenAspectRatio: " + screenAspectRatio);
|
Log.i(TAG, "screenAspectRatio: " + screenAspectRatio);
|
||||||
// Find a suitable size, with max resolution
|
// Find a suitable size, with max resolution
|
||||||
int maxResolution = 0;
|
int maxResolution = 0;
|
||||||
|
|
||||||
Camera.Size maxResPreviewSize = null;
|
Camera.Size maxResPreviewSize = null;
|
||||||
for (Camera.Size size : rawSupportedSizes) {
|
for (Camera.Size size : rawSupportedSizes) {
|
||||||
int realWidth = size.width;
|
int realWidth = size.width;
|
||||||
@@ -309,6 +315,7 @@ public final class CameraConfigurationUtils {
|
|||||||
int maybeFlippedWidth = isCandidatePortrait ? realWidth: realHeight ;
|
int maybeFlippedWidth = isCandidatePortrait ? realWidth: realHeight ;
|
||||||
int maybeFlippedHeight = isCandidatePortrait ? realHeight : realWidth;
|
int maybeFlippedHeight = isCandidatePortrait ? realHeight : realWidth;
|
||||||
Log.i(TAG, String.format("maybeFlipped:%d * %d",maybeFlippedWidth,maybeFlippedHeight));
|
Log.i(TAG, String.format("maybeFlipped:%d * %d",maybeFlippedWidth,maybeFlippedHeight));
|
||||||
|
|
||||||
double aspectRatio = maybeFlippedWidth / (double) maybeFlippedHeight;
|
double aspectRatio = maybeFlippedWidth / (double) maybeFlippedHeight;
|
||||||
Log.i(TAG, "aspectRatio: " + aspectRatio);
|
Log.i(TAG, "aspectRatio: " + aspectRatio);
|
||||||
double distortion = Math.abs(aspectRatio - screenAspectRatio);
|
double distortion = Math.abs(aspectRatio - screenAspectRatio);
|
||||||
@@ -330,21 +337,6 @@ public final class CameraConfigurationUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rawSupportedSizes.isEmpty()) {
|
|
||||||
Collections.sort(rawSupportedSizes, new Comparator<Camera.Size>() {
|
|
||||||
@Override
|
|
||||||
public int compare(Camera.Size o1, Camera.Size o2) {
|
|
||||||
int delta1 = Math.abs(o1.height-screenResolution.x);
|
|
||||||
int delta2 = Math.abs(o2.height-screenResolution.x);
|
|
||||||
return delta1 - delta2;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Camera.Size bestPreview = rawSupportedSizes.get(0);
|
|
||||||
Point bestSize = new Point(bestPreview.width, bestPreview.height);
|
|
||||||
Log.i(TAG, "Using largest suitable bestSize: " + bestSize);
|
|
||||||
return bestSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no exact match, use largest preview size. This was not a great idea on older devices because
|
// 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
|
// of the additional computation needed. We're likely to get here on newer Android 4+ devices, where
|
||||||
// the CPU is much more powerful.
|
// the CPU is much more powerful.
|
||||||
|
|||||||
@@ -31,10 +31,12 @@ import com.google.zxing.DecodeHintType;
|
|||||||
import com.google.zxing.EncodeHintType;
|
import com.google.zxing.EncodeHintType;
|
||||||
import com.google.zxing.MultiFormatReader;
|
import com.google.zxing.MultiFormatReader;
|
||||||
import com.google.zxing.MultiFormatWriter;
|
import com.google.zxing.MultiFormatWriter;
|
||||||
|
import com.google.zxing.NotFoundException;
|
||||||
import com.google.zxing.RGBLuminanceSource;
|
import com.google.zxing.RGBLuminanceSource;
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
import com.google.zxing.WriterException;
|
import com.google.zxing.WriterException;
|
||||||
import com.google.zxing.common.BitMatrix;
|
import com.google.zxing.common.BitMatrix;
|
||||||
|
import com.google.zxing.common.GlobalHistogramBinarizer;
|
||||||
import com.google.zxing.common.HybridBinarizer;
|
import com.google.zxing.common.HybridBinarizer;
|
||||||
import com.google.zxing.qrcode.QRCodeReader;
|
import com.google.zxing.qrcode.QRCodeReader;
|
||||||
import com.google.zxing.qrcode.QRCodeWriter;
|
import com.google.zxing.qrcode.QRCodeWriter;
|
||||||
@@ -188,7 +190,25 @@ public class CodeUtils {
|
|||||||
*/
|
*/
|
||||||
public static String parseQRCode(String bitmapPath, Map<DecodeHintType,?> hints){
|
public static String parseQRCode(String bitmapPath, Map<DecodeHintType,?> hints){
|
||||||
try {
|
try {
|
||||||
Result result = new QRCodeReader().decode(getBinaryBitmap(compressBitmap(bitmapPath)), hints);
|
QRCodeReader reader = new QRCodeReader();
|
||||||
|
|
||||||
|
Result result = null;
|
||||||
|
RGBLuminanceSource source = getRGBLuminanceSource(compressBitmap(bitmapPath));
|
||||||
|
if (source != null) {
|
||||||
|
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||||
|
try {
|
||||||
|
result = reader.decode(bitmap,hints);
|
||||||
|
} catch (Exception e) {//解析失败则通过GlobalHistogramBinarizer 再试一次
|
||||||
|
BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
|
||||||
|
try {
|
||||||
|
result = reader.decode(bitmap1);
|
||||||
|
} catch (NotFoundException ne) {
|
||||||
|
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
reader.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
return result.getText();
|
return result.getText();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -223,10 +243,27 @@ public class CodeUtils {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String parseCode(String bitmapPath, Map<DecodeHintType,Object> hints){
|
public static String parseCode(String bitmapPath, Map<DecodeHintType,Object> hints){
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MultiFormatReader reader = new MultiFormatReader();
|
MultiFormatReader reader = new MultiFormatReader();
|
||||||
reader.setHints(hints);
|
reader.setHints(hints);
|
||||||
Result result = reader.decodeWithState(getBinaryBitmap(compressBitmap(bitmapPath)));
|
Result result = null;
|
||||||
|
RGBLuminanceSource source = getRGBLuminanceSource(compressBitmap(bitmapPath));
|
||||||
|
if (source != null) {
|
||||||
|
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||||
|
try {
|
||||||
|
result = reader.decodeWithState(bitmap);
|
||||||
|
} catch (Exception e) {//解析失败则通过GlobalHistogramBinarizer 再试一次
|
||||||
|
BinaryBitmap bitmap1 = new BinaryBitmap(new GlobalHistogramBinarizer(source));
|
||||||
|
try {
|
||||||
|
result = reader.decodeWithState(bitmap1);
|
||||||
|
} catch (NotFoundException ne) {
|
||||||
|
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
reader.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
return result.getText();
|
return result.getText();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -234,6 +271,8 @@ public class CodeUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 压缩图片
|
* 压缩图片
|
||||||
* @param path
|
* @param path
|
||||||
@@ -265,19 +304,18 @@ public class CodeUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取二进制图片
|
* 获取RGBLuminanceSource
|
||||||
* @param bitmap
|
* @param bitmap
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static BinaryBitmap getBinaryBitmap(@NonNull Bitmap bitmap){
|
private static RGBLuminanceSource getRGBLuminanceSource(@NonNull Bitmap bitmap){
|
||||||
int width = bitmap.getWidth();
|
int width = bitmap.getWidth();
|
||||||
int height = bitmap.getHeight();
|
int height = bitmap.getHeight();
|
||||||
|
|
||||||
int[] pixels = new int[width * height];
|
int[] pixels = new int[width * height];
|
||||||
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
|
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||||
RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
|
return new RGBLuminanceSource(width, height, pixels);
|
||||||
//得到二进制图片
|
|
||||||
return new BinaryBitmap(new HybridBinarizer(source));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//App
|
//App
|
||||||
def app_version = [:]
|
def app_version = [:]
|
||||||
app_version.versionCode = 6
|
app_version.versionCode = 7
|
||||||
app_version.versionName = "1.0.5"
|
app_version.versionName = "1.0.6"
|
||||||
ext.app_version = app_version
|
ext.app_version = app_version
|
||||||
|
|
||||||
//build version
|
//build version
|
||||||
|
|||||||
Reference in New Issue
Block a user