diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index 3545368..435043e 100644
Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ
diff --git a/README.md b/README.md
index 674e6cc..c95ff23 100644
--- a/README.md
+++ b/README.md
@@ -36,17 +36,17 @@ ZXingLite for Android 是ZXing的精简版,优化扫码和生成二维码功
com.king.zxing
zxing-lite
- 1.0.1
+ 1.0.2
pom
```
### Gradle:
```gradle
-implementation 'com.king.zxing:zxing-lite:1.0.1'
+implementation 'com.king.zxing:zxing-lite:1.0.2'
```
### Lvy:
```lvy
-
+
```
diff --git a/app/release/app-release.apk b/app/release/app-release.apk
index 724f40e..2d1f2cf 100644
Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 507eb1a..494edf2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,10 @@
+
+
+
+
cls;
private String title;
@@ -53,15 +66,48 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- if(resultCode == RESULT_OK){
- if(data!=null){
- //识别结果
- String result = data.getStringExtra(Intents.Scan.RESULT);
- Toast.makeText(this,result,Toast.LENGTH_SHORT).show();
+ if(resultCode == RESULT_OK && data!=null){
+ switch (requestCode){
+ case REQUEST_CODE_SCAN:
+ String result = data.getStringExtra(Intents.Scan.RESULT);
+ Toast.makeText(this,result,Toast.LENGTH_SHORT).show();
+ break;
+ case REQUEST_CODE_PHOTO:
+ parsePhoto(data);
+ break;
}
+
}
}
+ private void parsePhoto(Intent data){
+ final String path = UriUtils.INSTANCE.getImagePath(this,data);
+ Log.d("Jenly","path:" + path);
+ if(TextUtils.isEmpty(path)){
+ return;
+ }
+ //异步解析
+ asyncThread(new Runnable() {
+ @Override
+ public void run() {
+ final String result = CodeUtils.parseCode(path);
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Log.d("Jenly","result:" + result);
+ Toast.makeText(getContext(),result,Toast.LENGTH_SHORT).show();
+ }
+ });
+
+ }
+ });
+
+ }
+
+ private Context getContext(){
+ return this;
+ }
+
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@@ -73,7 +119,12 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
@Override
public void onPermissionsGranted(int requestCode, List list) {
// Some permissions have been granted
- startScan(cls,title);
+ switch (requestCode){
+ case RC_CAMERA:
+ startScan(cls,title);
+ break;
+ }
+
}
@Override
@@ -101,6 +152,10 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
}
}
+ private void asyncThread(Runnable runnable){
+ new Thread(runnable).start();
+ }
+
/**
* 扫码
* @param cls
@@ -110,7 +165,7 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeCustomAnimation(this,R.anim.in,R.anim.out);
Intent intent = new Intent(this, cls);
intent.putExtra(KEY_TITLE,title);
- ActivityCompat.startActivityForResult(this,intent,REQUEST_CODE,optionsCompat.toBundle());
+ ActivityCompat.startActivityForResult(this,intent,REQUEST_CODE_SCAN,optionsCompat.toBundle());
}
/**
@@ -124,6 +179,24 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
startActivity(intent);
}
+ private void startPhotoCode(){
+ Intent pickIntent = new Intent(Intent.ACTION_PICK,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+ pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
+ startActivityForResult(pickIntent, REQUEST_CODE_PHOTO);
+ }
+
+ @AfterPermissionGranted(RC_READ_PHOTO)
+ private void checkExternalStoragePermissions(){
+ String[] perms = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};
+ if (EasyPermissions.hasPermissions(this, perms)) {//有权限
+ startPhotoCode();
+ }else{
+ EasyPermissions.requestPermissions(this, getString(R.string.permission_external_storage),
+ RC_READ_PHOTO, perms);
+ }
+ }
+
public void OnClick(View v){
switch (v.getId()){
case R.id.btn1:
@@ -141,6 +214,9 @@ public class MainActivity extends AppCompatActivity implements EasyPermissions.P
case R.id.btn5:
startCode(true);
break;
+ case R.id.btn6:
+ checkExternalStoragePermissions();
+ break;
}
}
diff --git a/app/src/main/java/com/king/zxing/app/util/UriUtils.java b/app/src/main/java/com/king/zxing/app/util/UriUtils.java
new file mode 100644
index 0000000..ea8e899
--- /dev/null
+++ b/app/src/main/java/com/king/zxing/app/util/UriUtils.java
@@ -0,0 +1,69 @@
+package com.king.zxing.app.util;
+
+import android.annotation.TargetApi;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.provider.DocumentsContract;
+import android.provider.MediaStore;
+import android.util.Log;
+
+/**
+ * @author Jenly Jenly
+ */
+public enum UriUtils {
+ INSTANCE;
+
+ /**
+ * 获取图片
+ */
+ public String getImagePath(Context context,Intent data) {
+ String imagePath = null;
+ Uri uri = data.getData();
+ //获取系統版本
+ int currentapiVersion = Build.VERSION.SDK_INT;
+ if(currentapiVersion> Build.VERSION_CODES.KITKAT){
+ Log.d("uri=intent.getData :", "" + uri);
+ if (DocumentsContract.isDocumentUri(context, uri)) {
+ String docId = DocumentsContract.getDocumentId(uri);
+ Log.d("getDocumentId(uri) :", "" + docId);
+ Log.d("uri.getAuthority() :", "" + uri.getAuthority());
+ if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
+ String id = docId.split(":")[1];
+ String selection = MediaStore.Images.Media._ID + "=" + id;
+ imagePath = getImagePath(context,MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
+ } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
+ Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
+ imagePath = getImagePath(context,contentUri, null);
+ }
+
+ } else if ("content".equalsIgnoreCase(uri.getScheme())) {
+ imagePath = getImagePath(context,uri, null);
+ }
+ }else{
+ imagePath = getImagePath(context,uri, null);
+ }
+
+ return imagePath;
+
+ }
+
+ /**
+ * 通过uri和selection来获取真实的图片路径,从相册获取图片时要用
+ */
+ private String getImagePath(Context context,Uri uri, String selection) {
+ String path = null;
+ Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
+ if (cursor != null) {
+ if (cursor.moveToFirst()) {
+ path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
+ }
+ cursor.close();
+ }
+ return path;
+ }
+
+}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index d5e0398..b2a2a47 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -98,4 +98,17 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn4"
style="@style/OnClick"/>
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d58c21e..1e791cf 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,6 +1,7 @@
ZXingLite
App扫码需要用到拍摄权限
+ App需要用到读写权限
将二维码/条形码放入框内,即可自动扫码
二维码
条形码
diff --git a/lib/src/main/AndroidManifest.xml b/lib/src/main/AndroidManifest.xml
index 5203089..885f413 100644
--- a/lib/src/main/AndroidManifest.xml
+++ b/lib/src/main/AndroidManifest.xml
@@ -5,12 +5,10 @@
-
-
-
+
PRODUCT_FORMATS;
- static final Set INDUSTRIAL_FORMATS;
- private static final Set ONE_D_FORMATS;
- static final Set QR_CODE_FORMATS = EnumSet.of(BarcodeFormat.QR_CODE);
- static final Set DATA_MATRIX_FORMATS = EnumSet.of(BarcodeFormat.DATA_MATRIX);
- static final Set AZTEC_FORMATS = EnumSet.of(BarcodeFormat.AZTEC);
- static final Set PDF417_FORMATS = EnumSet.of(BarcodeFormat.PDF_417);
+ public static final Set PRODUCT_FORMATS;
+ public static final Set INDUSTRIAL_FORMATS;
+ public static final Set ONE_D_FORMATS;
+ public static final Set QR_CODE_FORMATS = EnumSet.of(BarcodeFormat.QR_CODE);
+ public static final Set DATA_MATRIX_FORMATS = EnumSet.of(BarcodeFormat.DATA_MATRIX);
+ public static final Set AZTEC_FORMATS = EnumSet.of(BarcodeFormat.AZTEC);
+ public static final Set PDF417_FORMATS = EnumSet.of(BarcodeFormat.PDF_417);
static {
PRODUCT_FORMATS = EnumSet.of(BarcodeFormat.UPC_A,
BarcodeFormat.UPC_E,
diff --git a/lib/src/main/java/com/king/zxing/DecodeHandler.java b/lib/src/main/java/com/king/zxing/DecodeHandler.java
index 80c9d0d..fd47e76 100644
--- a/lib/src/main/java/com/king/zxing/DecodeHandler.java
+++ b/lib/src/main/java/com/king/zxing/DecodeHandler.java
@@ -74,7 +74,15 @@ final class DecodeHandler extends Handler {
private void decode(byte[] data, int width, int height) {
long start = System.currentTimeMillis();
Result rawResult = null;
- PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
+ byte[] rotatedData = new byte[data.length];
+ 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;
+ PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(rotatedData, width, height);
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
diff --git a/lib/src/main/java/com/king/zxing/DecodeHintManager.java b/lib/src/main/java/com/king/zxing/DecodeHintManager.java
index a3caf4b..0eae52f 100644
--- a/lib/src/main/java/com/king/zxing/DecodeHintManager.java
+++ b/lib/src/main/java/com/king/zxing/DecodeHintManager.java
@@ -32,7 +32,7 @@ import com.google.zxing.DecodeHintType;
/**
* @author Lachezar Dobrev
*/
-final class DecodeHintManager {
+public final class DecodeHintManager {
private static final String TAG = DecodeHintManager.class.getSimpleName();
diff --git a/lib/src/main/java/com/king/zxing/ViewfinderView.java b/lib/src/main/java/com/king/zxing/ViewfinderView.java
index b762475..cdcbd01 100644
--- a/lib/src/main/java/com/king/zxing/ViewfinderView.java
+++ b/lib/src/main/java/com/king/zxing/ViewfinderView.java
@@ -85,6 +85,7 @@ public final class ViewfinderView extends View {
private final float labelTextSize;
public static int scannerStart = 0;
public static int scannerEnd = 0;
+ private boolean isShowResultPoint;
private List possibleResultPoints;
private List lastPossibleResultPoints;
@@ -320,7 +321,15 @@ public final class ViewfinderView extends View {
invalidate();
}
-// /**
+ public boolean isShowResultPoint() {
+ return isShowResultPoint;
+ }
+
+ public void setShowResultPoint(boolean showResultPoint) {
+ isShowResultPoint = showResultPoint;
+ }
+
+ // /**
// * Draw a bitmap with the result points highlighted instead of the live scanning display.
// *
// * @param barcode An image of the decoded barcode.
@@ -331,15 +340,18 @@ public final class ViewfinderView extends View {
// }
public void addPossibleResultPoint(ResultPoint point) {
- List points = possibleResultPoints;
- synchronized (points) {
- points.add(point);
- int size = points.size();
- if (size > MAX_RESULT_POINTS) {
- // trim it
- points.subList(0, size - MAX_RESULT_POINTS / 2).clear();
+ if(isShowResultPoint){
+ List points = possibleResultPoints;
+ synchronized (points) {
+ points.add(point);
+ int size = points.size();
+ if (size > MAX_RESULT_POINTS) {
+ // trim it
+ points.subList(0, size - MAX_RESULT_POINTS / 2).clear();
+ }
}
}
+
}
}
\ No newline at end of file
diff --git a/lib/src/main/java/com/king/zxing/camera/CameraConfigurationManager.java b/lib/src/main/java/com/king/zxing/camera/CameraConfigurationManager.java
index 871b714..f1fc216 100644
--- a/lib/src/main/java/com/king/zxing/camera/CameraConfigurationManager.java
+++ b/lib/src/main/java/com/king/zxing/camera/CameraConfigurationManager.java
@@ -123,6 +123,7 @@ final class CameraConfigurationManager {
display.getSize(theScreenResolution);
screenResolution = theScreenResolution;
Log.i(TAG, "Screen resolution in current orientation: " + screenResolution);
+
cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
Log.i(TAG, "Camera resolution: " + cameraResolution);
bestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
@@ -157,6 +158,9 @@ final class CameraConfigurationManager {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ theCamera.setDisplayOrientation(90);
+ theCamera.setParameters(parameters);
+
initializeTorch(parameters, prefs, safeMode);
CameraConfigurationUtils.setFocus(
diff --git a/lib/src/main/java/com/king/zxing/camera/CameraConfigurationUtils.java b/lib/src/main/java/com/king/zxing/camera/CameraConfigurationUtils.java
index 2d07bfb..ebddc20 100644
--- a/lib/src/main/java/com/king/zxing/camera/CameraConfigurationUtils.java
+++ b/lib/src/main/java/com/king/zxing/camera/CameraConfigurationUtils.java
@@ -25,6 +25,7 @@ import android.util.Log;
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;
@@ -44,7 +45,7 @@ public final class CameraConfigurationUtils {
private static final int MIN_PREVIEW_PIXELS = 480 * 320; // normal screen
private static final float MAX_EXPOSURE_COMPENSATION = 1.5f;
private static final float MIN_EXPOSURE_COMPENSATION = 0.0f;
- private static final double MAX_ASPECT_DISTORTION = 0.15;
+ private static final double MAX_ASPECT_DISTORTION = 0.10;
private static final int MIN_FPS = 10;
private static final int MAX_FPS = 20;
private static final int AREA_PER_1000 = 400;
@@ -270,7 +271,7 @@ public final class CameraConfigurationUtils {
}
}
- public static Point findBestPreviewSizeValue(Camera.Parameters parameters, Point screenResolution) {
+ public static Point findBestPreviewSizeValue(Camera.Parameters parameters,final Point screenResolution) {
List rawSupportedSizes = parameters.getSupportedPreviewSizes();
if (rawSupportedSizes == null) {
@@ -282,6 +283,7 @@ public final class CameraConfigurationUtils {
return new Point(defaultSize.width, defaultSize.height);
}
+
if (Log.isLoggable(TAG, Log.INFO)) {
StringBuilder previewSizesString = new StringBuilder();
for (Camera.Size size : rawSupportedSizes) {
@@ -291,7 +293,7 @@ public final class CameraConfigurationUtils {
}
double screenAspectRatio = screenResolution.x / (double) screenResolution.y;
-
+ Log.i(TAG, "screenAspectRatio: " + screenAspectRatio);
// Find a suitable size, with max resolution
int maxResolution = 0;
Camera.Size maxResPreviewSize = null;
@@ -304,10 +306,13 @@ public final class CameraConfigurationUtils {
}
boolean isCandidatePortrait = realWidth < realHeight;
- int maybeFlippedWidth = isCandidatePortrait ? realHeight : realWidth;
- int maybeFlippedHeight = isCandidatePortrait ? realWidth : realHeight;
+ int maybeFlippedWidth = isCandidatePortrait ? realWidth: realHeight ;
+ int maybeFlippedHeight = isCandidatePortrait ? realHeight : realWidth;
+ Log.i(TAG, String.format("maybeFlipped:%d * %d",maybeFlippedWidth,maybeFlippedHeight));
double aspectRatio = maybeFlippedWidth / (double) maybeFlippedHeight;
+ Log.i(TAG, "aspectRatio: " + aspectRatio);
double distortion = Math.abs(aspectRatio - screenAspectRatio);
+ Log.i(TAG, "distortion: " + distortion);
if (distortion > MAX_ASPECT_DISTORTION) {
continue;
}
@@ -325,6 +330,21 @@ public final class CameraConfigurationUtils {
}
}
+ if (!rawSupportedSizes.isEmpty()) {
+ Collections.sort(rawSupportedSizes, new Comparator() {
+ @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
// of the additional computation needed. We're likely to get here on newer Android 4+ devices, where
// the CPU is much more powerful.
diff --git a/lib/src/main/java/com/king/zxing/camera/CameraManager.java b/lib/src/main/java/com/king/zxing/camera/CameraManager.java
index 976b312..d8cb8b6 100644
--- a/lib/src/main/java/com/king/zxing/camera/CameraManager.java
+++ b/lib/src/main/java/com/king/zxing/camera/CameraManager.java
@@ -271,6 +271,12 @@ public final class CameraManager {
// 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;
+
framingRectInPreview = rect;
}
return framingRectInPreview;
diff --git a/lib/src/main/java/com/king/zxing/util/CodeUtils.java b/lib/src/main/java/com/king/zxing/util/CodeUtils.java
index 1f0ac42..5180df9 100644
--- a/lib/src/main/java/com/king/zxing/util/CodeUtils.java
+++ b/lib/src/main/java/com/king/zxing/util/CodeUtils.java
@@ -16,19 +16,36 @@
package com.king.zxing.util;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
+import android.text.TextPaint;
import android.text.TextUtils;
import com.google.zxing.BarcodeFormat;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.RGBLuminanceSource;
+import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
+import com.google.zxing.common.HybridBinarizer;
+import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import com.king.zxing.DecodeFormatManager;
+import com.king.zxing.DecodeHintManager;
import java.util.HashMap;
+import java.util.Hashtable;
import java.util.Map;
+import java.util.Vector;
/**
@@ -144,17 +161,127 @@ public class CodeUtils {
canvas.drawBitmap(src, 0, 0, null);
canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);
canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);
-
canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
} catch (Exception e) {
bitmap = null;
- e.getStackTrace();
+ e.printStackTrace();
}
return bitmap;
}
+ /**
+ * 解析二维码图片
+ * @param bitmapPath
+ * @return
+ */
+ public static String parseQRCode(String bitmapPath) {
+ Map hints = new HashMap<>();
+ hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
+ return parseQRCode(bitmapPath,hints);
+ }
+
+ /**
+ * 解析二维码图片
+ * @param bitmapPath
+ * @param hints
+ * @return
+ */
+ public static String parseQRCode(String bitmapPath, Map hints){
+ try {
+ Result result = new QRCodeReader().decode(getBinaryBitmap(compressBitmap(bitmapPath)), hints);
+ return result.getText();
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ return null;
+ }
+
+ /**
+ * 解析一维码/二维码图片
+ * @param bitmapPath
+ * @return
+ */
+ public static String parseCode(String bitmapPath){
+ Map hints = new HashMap<>();
+ //添加可以解析的编码类型
+ Vector decodeFormats = new Vector<>();
+ decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
+ decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
+ decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
+ decodeFormats.addAll(DecodeFormatManager.AZTEC_FORMATS);
+ decodeFormats.addAll(DecodeFormatManager.PDF417_FORMATS);
+
+ hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
+ return parseCode(bitmapPath,hints);
+ }
+
+ /**
+ * 解析一维码/二维码图片
+ * @param bitmapPath
+ * @param hints 解析编码类型
+ * @return
+ */
+ public static String parseCode(String bitmapPath, Map hints){
+ try {
+ MultiFormatReader reader = new MultiFormatReader();
+ reader.setHints(hints);
+ Result result = reader.decodeWithState(getBinaryBitmap(compressBitmap(bitmapPath)));
+ return result.getText();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 压缩图片
+ * @param path
+ * @return
+ */
+ private static Bitmap compressBitmap(String path){
+
+ BitmapFactory.Options newOpts = new BitmapFactory.Options();
+ // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
+ newOpts.inJustDecodeBounds = true;//获取原始图片大小
+ BitmapFactory.decodeFile(path, newOpts);// 此时返回bm为空
+ int w = newOpts.outWidth;
+ 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);
+ } else if (w < h && h > height) {// 如果高度高的话根据宽度固定大小缩放
+ be = (int) (newOpts.outHeight / height);
+ }
+ if (be <= 0)
+ be = 1;
+ newOpts.inSampleSize = be;// 设置缩放比例
+ // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
+ newOpts.inJustDecodeBounds = false;
+ return BitmapFactory.decodeFile(path, newOpts);
+ }
+
+ /**
+ * 获取二进制图片
+ * @param bitmap
+ * @return
+ */
+ private static BinaryBitmap getBinaryBitmap(@NonNull Bitmap bitmap){
+ int width = bitmap.getWidth();
+ int height = bitmap.getHeight();
+
+ int[] pixels = new int[width * height];
+ bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
+ RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
+ //得到二进制图片
+ return new BinaryBitmap(new HybridBinarizer(source));
+ }
+
/**
* 生成条形码
* @param content
@@ -167,6 +294,7 @@ public class CodeUtils {
return createBarCode(content,format,desiredWidth,desiredHeight,null);
}
+
/**
* 生成条形码
* @param content
@@ -176,7 +304,37 @@ public class CodeUtils {
* @param hints
* @return
*/
- public static Bitmap createBarCode(String content,BarcodeFormat format, int desiredWidth, int desiredHeight,Map hints) {
+ public static Bitmap createBarCode(String content, BarcodeFormat format, int desiredWidth, int desiredHeight, Map hints) {
+ return createBarCode(content,format,desiredWidth,desiredHeight,hints,false,40,Color.BLACK);
+ }
+
+ /**
+ * 生成条形码
+ * @param content
+ * @param format
+ * @param desiredWidth
+ * @param desiredHeight
+ * @param hints
+ * @param isShowText
+ * @return
+ */
+ public static Bitmap createBarCode(String content, BarcodeFormat format, int desiredWidth, int desiredHeight, Map hints, boolean isShowText) {
+ return createBarCode(content,format,desiredWidth,desiredHeight,hints,isShowText,40,Color.BLACK);
+ }
+
+ /**
+ * 生成条形码
+ * @param content
+ * @param format
+ * @param desiredWidth
+ * @param desiredHeight
+ * @param hints
+ * @param isShowText
+ * @param textSize
+ * @param textColor
+ * @return
+ */
+ public static Bitmap createBarCode(String content,BarcodeFormat format, int desiredWidth, int desiredHeight,Map hints,boolean isShowText,int textSize,@ColorInt int textColor) {
if(TextUtils.isEmpty(content)){
return null;
}
@@ -201,6 +359,9 @@ public class CodeUtils {
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
+ if(isShowText){
+ return addCode(bitmap,content,textSize,textColor,textSize/2);
+ }
return bitmap;
} catch (WriterException e) {
e.printStackTrace();
@@ -208,4 +369,48 @@ public class CodeUtils {
return null;
}
+ /**
+ * 条形码下面添加文本信息
+ * @param src
+ * @param code
+ * @param textSize
+ * @param textColor
+ * @return
+ */
+ private static Bitmap addCode(Bitmap src,String code,int textSize,@ColorInt int textColor,int offset) {
+ if (src == null) {
+ return null;
+ }
+
+ if (TextUtils.isEmpty(code)) {
+ return src;
+ }
+
+ //获取图片的宽高
+ int srcWidth = src.getWidth();
+ int srcHeight = src.getHeight();
+
+ if (srcWidth <= 0 || srcHeight <= 0) {
+ return null;
+ }
+
+ Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight + textSize + offset * 2, Bitmap.Config.ARGB_8888);
+ try {
+ Canvas canvas = new Canvas(bitmap);
+ canvas.drawBitmap(src, 0, 0, null);
+ TextPaint paint = new TextPaint();
+ paint.setTextSize(textSize);
+ paint.setColor(textColor);
+ paint.setTextAlign(Paint.Align.CENTER);
+ canvas.drawText(code,srcWidth/2,srcHeight + textSize /2 + offset,paint);
+ canvas.save(Canvas.ALL_SAVE_FLAG);
+ canvas.restore();
+ } catch (Exception e) {
+ bitmap = null;
+ e.printStackTrace();
+ }
+
+ return bitmap;
+ }
+
}
diff --git a/versions.gradle b/versions.gradle
index 7c65fd7..6a20242 100644
--- a/versions.gradle
+++ b/versions.gradle
@@ -1,7 +1,7 @@
//App
def app_version = [:]
-app_version.versionCode = 2
-app_version.versionName = "1.0.1"
+app_version.versionCode = 3
+app_version.versionName = "1.0.2"
ext.app_version = app_version
//build version