发布v3.2.0
This commit is contained in:
@ -35,8 +35,7 @@ ZXingLite for Android 是ZXing的精简极速版,基于ZXing库优化扫码和
|
||||
2. 在Module的 **build.gradle** 里面添加引入依赖项
|
||||
|
||||
```gradle
|
||||
// AndroidX 版本
|
||||
implementation 'com.github.jenly1314:zxing-lite:3.1.1'
|
||||
implementation 'com.github.jenly1314:zxing-lite:3.2.0'
|
||||
|
||||
```
|
||||
|
||||
@ -202,6 +201,11 @@ dependencies {
|
||||
|
||||
## 版本记录
|
||||
|
||||
#### v3.2.0:2024-07-16
|
||||
* 更新CameraScan至v1.2.0
|
||||
* 更新ViewfinderView至v1.2.0
|
||||
* 优化细节
|
||||
|
||||
#### v3.1.1:2024-04-29
|
||||
* 更新CameraScan至v1.1.1
|
||||
* 更新zxing至v3.5.3
|
||||
|
||||
@ -25,11 +25,11 @@ android {
|
||||
}
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_11.toString()
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
|
||||
Binary file not shown.
@ -11,8 +11,8 @@
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"attributes": [],
|
||||
"versionCode": 41,
|
||||
"versionName": "3.1.1",
|
||||
"versionCode": 42,
|
||||
"versionName": "3.2.0",
|
||||
"outputFile": "app-release.apk"
|
||||
}
|
||||
],
|
||||
|
||||
@ -33,7 +33,10 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
/**
|
||||
* 生成条形码/二维码示例
|
||||
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
public class CodeActivity extends AppCompatActivity {
|
||||
|
||||
|
||||
@ -16,7 +16,10 @@ import com.king.zxing.analyze.QRCodeAnalyzer
|
||||
|
||||
/**
|
||||
* 扫二维码全屏识别示例
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
class FullScreenQRCodeScanActivity : BarcodeCameraScanActivity() {
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
@ -28,7 +29,6 @@ import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
|
||||
import com.king.camera.scan.CameraScan;
|
||||
import com.king.camera.scan.util.LogUtils;
|
||||
import com.king.zxing.util.CodeUtils;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@ -36,9 +36,14 @@ import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* 扫码示例
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private static final String TAG = "MainActivity";
|
||||
public static final String KEY_TITLE = "key_title";
|
||||
public static final String KEY_IS_QR_CODE = "key_code";
|
||||
|
||||
@ -88,8 +93,10 @@ public class MainActivity extends AppCompatActivity {
|
||||
//异步解析
|
||||
asyncThread(() -> {
|
||||
final String result = CodeUtils.parseCode(bitmap);
|
||||
// 如果只需识别二维码,建议使用:parseQRCode;(因为识别的格式越明确,误识别率越低。)
|
||||
// final String result = CodeUtils.parseQRCode(bitmap);
|
||||
runOnUiThread(() -> {
|
||||
LogUtils.d("result:" + result);
|
||||
Log.d(TAG, "result:" + result);
|
||||
showToast(result);
|
||||
});
|
||||
|
||||
|
||||
@ -11,7 +11,10 @@ import com.king.zxing.analyze.MultiFormatAnalyzer
|
||||
|
||||
/**
|
||||
* 连续扫码(识别多种格式)示例
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
class MultiFormatScanActivity : BarcodeCameraScanActivity() {
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import com.king.camera.scan.analyze.Analyzer;
|
||||
import com.king.zxing.DecodeConfig;
|
||||
import com.king.zxing.DecodeFormatManager;
|
||||
import com.king.zxing.BarcodeCameraScanActivity;
|
||||
import com.king.zxing.analyze.MultiFormatAnalyzer;
|
||||
import com.king.zxing.analyze.QRCodeAnalyzer;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -17,7 +18,10 @@ import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* 扫二维码识别示例
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
public class QRCodeScanActivity extends BarcodeCameraScanActivity {
|
||||
|
||||
@ -38,8 +42,8 @@ public class QRCodeScanActivity extends BarcodeCameraScanActivity {
|
||||
.setAreaRectRatio(0.8f)//设置识别区域比例,默认0.8,设置的比例最终会在预览区域裁剪基于此比例的一个矩形进行扫码识别
|
||||
.setAreaRectVerticalOffset(0)//设置识别区域垂直方向偏移量,默认为0,为0表示居中,可以为负数
|
||||
.setAreaRectHorizontalOffset(0);//设置识别区域水平方向偏移量,默认为0,为0表示居中,可以为负数
|
||||
// BarcodeCameraScanActivity默认使用的MultiFormatAnalyzer,这里可以改为使用QRCodeAnalyzer
|
||||
return new QRCodeAnalyzer(decodeConfig);
|
||||
// BarcodeCameraScanActivity默认使用的MultiFormatAnalyzer,这里也可以改为使用QRCodeAnalyzer
|
||||
return new MultiFormatAnalyzer(decodeConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
## 版本记录
|
||||
|
||||
#### v3.2.0:2024-07-16
|
||||
* 更新CameraScan至v1.2.0
|
||||
* 更新ViewfinderView至v1.2.0
|
||||
* 优化细节
|
||||
|
||||
#### v3.1.1:2024-04-29
|
||||
* 更新CameraScan至v1.1.1
|
||||
* 更新zxing至v3.5.3
|
||||
|
||||
@ -18,8 +18,8 @@ android.defaults.buildfeatures.buildconfig=true
|
||||
android.nonTransitiveRClass=false
|
||||
android.nonFinalResIds=false
|
||||
|
||||
VERSION_NAME=3.1.1
|
||||
VERSION_CODE=41
|
||||
VERSION_NAME=3.2.0
|
||||
VERSION_CODE=42
|
||||
GROUP=com.github.jenly1314
|
||||
|
||||
POM_DESCRIPTION=ZXingLite for Android
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// App
|
||||
def app_version = [:]
|
||||
app_version.versionCode = 41
|
||||
app_version.versionName = "3.1.1"
|
||||
app_version.versionCode = 42
|
||||
app_version.versionName = "3.2.0"
|
||||
ext.app_version = app_version
|
||||
|
||||
// build version
|
||||
@ -50,9 +50,9 @@ deps.test = test
|
||||
deps.zxing = "com.google.zxing:core:3.5.3"
|
||||
|
||||
// CameraScan
|
||||
deps.camera_scan = "com.github.jenly1314:camera-scan:1.1.1"
|
||||
deps.camera_scan = "com.github.jenly1314:camera-scan:1.2.0"
|
||||
// ViewfinderView
|
||||
deps.viewfinderview = "com.github.jenly1314:viewfinderview:1.1.0"
|
||||
deps.viewfinderview = "com.github.jenly1314:viewfinderview:1.2.0"
|
||||
|
||||
// desugar_jdk
|
||||
deps.desugar_jdk = "com.android.tools:desugar_jdk_libs:1.2.3"
|
||||
|
||||
@ -24,8 +24,8 @@ android {
|
||||
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
|
||||
@ -16,6 +16,8 @@ import androidx.annotation.Nullable;
|
||||
* 通过继承 {@link BarcodeCameraScanActivity}或{@link BarcodeCameraScanFragment}可快速实现扫码识别
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
public abstract class BarcodeCameraScanActivity extends BaseCameraScanActivity<Result> {
|
||||
|
||||
|
||||
@ -16,6 +16,8 @@ import androidx.annotation.Nullable;
|
||||
* 通过继承 {@link BarcodeCameraScanActivity}或{@link BarcodeCameraScanFragment}可快速实现扫码识别
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
public abstract class BarcodeCameraScanFragment extends BaseCameraScanFragment<Result> {
|
||||
|
||||
|
||||
@ -2,6 +2,9 @@ package com.king.zxing;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
import androidx.annotation.FloatRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.common.GlobalHistogramBinarizer;
|
||||
@ -9,8 +12,6 @@ import com.google.zxing.common.HybridBinarizer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.annotation.FloatRange;
|
||||
|
||||
/**
|
||||
* 解码配置:主要用于在扫码识别时,提供一些配置,便于扩展。通过配置可决定内置分析器的能力,从而间接的控制并简化扫码识别的流程
|
||||
* <p></>
|
||||
@ -25,7 +26,6 @@ import androidx.annotation.FloatRange;
|
||||
* {@link DecodeFormatManager#DEFAULT_HINTS}
|
||||
* <p>
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* 如果不满足您也可以通过{@link DecodeFormatManager#createDecodeHints(BarcodeFormat...)}自己配置支持的格式
|
||||
*
|
||||
@ -38,7 +38,11 @@ import androidx.annotation.FloatRange;
|
||||
* 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域,
|
||||
* <p>
|
||||
* 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)}
|
||||
* <p></>
|
||||
* <p>
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class DecodeConfig {
|
||||
@ -325,7 +329,7 @@ public class DecodeConfig {
|
||||
/**
|
||||
* 设置识别区域垂直方向偏移量,支持负数,大于0时,居中心向下偏移,小于0时,居中心向上偏移
|
||||
*
|
||||
* @param areaRectVerticalOffset
|
||||
* @param areaRectVerticalOffset 识别区域垂直方向偏移量
|
||||
* @return {@link DecodeConfig}
|
||||
*/
|
||||
public DecodeConfig setAreaRectVerticalOffset(int areaRectVerticalOffset) {
|
||||
@ -345,7 +349,7 @@ public class DecodeConfig {
|
||||
/**
|
||||
* 设置识别区域水平方向偏移量,支持负数,大于0时,居中心向右偏移,小于0时,居中心向左偏移
|
||||
*
|
||||
* @param areaRectHorizontalOffset
|
||||
* @param areaRectHorizontalOffset 识别区域水平方向偏移量
|
||||
* @return {@link DecodeConfig}
|
||||
*/
|
||||
public DecodeConfig setAreaRectHorizontalOffset(int areaRectHorizontalOffset) {
|
||||
@ -353,6 +357,7 @@ public class DecodeConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DecodeConfig{" +
|
||||
|
||||
@ -18,11 +18,13 @@ import androidx.annotation.NonNull;
|
||||
* 将常见的一些解码配置已根据条形码类型进行了几大划分,可根据需要找到符合的划分配置类型直接使用。
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
public final class DecodeFormatManager {
|
||||
|
||||
/**
|
||||
* 所有的
|
||||
* 所有的支持的条码
|
||||
*/
|
||||
public static final Map<DecodeHintType, Object> ALL_HINTS = new EnumMap<>(DecodeHintType.class);
|
||||
/**
|
||||
@ -62,9 +64,9 @@ public final class DecodeFormatManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有支持的{@link BarcodeFormat}
|
||||
* 所有支持的条码格式,具体格式可查看:{@link BarcodeFormat}
|
||||
*
|
||||
* @return
|
||||
* @return 所有支持的条码格式
|
||||
*/
|
||||
private static List<BarcodeFormat> getAllFormats() {
|
||||
List<BarcodeFormat> list = new ArrayList<>();
|
||||
@ -90,6 +92,7 @@ public final class DecodeFormatManager {
|
||||
|
||||
/**
|
||||
* 一维码
|
||||
* <p>
|
||||
* 包括如下几种格式:
|
||||
* {@link BarcodeFormat#CODABAR}
|
||||
* {@link BarcodeFormat#CODE_39}
|
||||
@ -104,7 +107,7 @@ public final class DecodeFormatManager {
|
||||
* {@link BarcodeFormat#UPC_E}
|
||||
* {@link BarcodeFormat#UPC_EAN_EXTENSION}
|
||||
*
|
||||
* @return
|
||||
* @return 需要支持的一维码格式
|
||||
*/
|
||||
private static List<BarcodeFormat> getOneDimensionalFormats() {
|
||||
List<BarcodeFormat> list = new ArrayList<>();
|
||||
@ -124,7 +127,8 @@ public final class DecodeFormatManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* 二维码
|
||||
* 二维码,具体格式可查看:{@link BarcodeFormat}
|
||||
* <p>
|
||||
* 包括如下几种格式:
|
||||
* {@link BarcodeFormat#AZTEC}
|
||||
* {@link BarcodeFormat#DATA_MATRIX}
|
||||
@ -132,7 +136,7 @@ public final class DecodeFormatManager {
|
||||
* {@link BarcodeFormat#PDF_417}
|
||||
* {@link BarcodeFormat#QR_CODE}
|
||||
*
|
||||
* @return
|
||||
* @return 需要支持的二维码格式
|
||||
*/
|
||||
private static List<BarcodeFormat> getTwoDimensionalFormats() {
|
||||
List<BarcodeFormat> list = new ArrayList<>();
|
||||
@ -146,13 +150,14 @@ public final class DecodeFormatManager {
|
||||
|
||||
/**
|
||||
* 默认支持的格式
|
||||
* <p>
|
||||
* 包括如下几种格式:
|
||||
* {@link BarcodeFormat#QR_CODE}
|
||||
* {@link BarcodeFormat#UPC_A}
|
||||
* {@link BarcodeFormat#EAN_13}
|
||||
* {@link BarcodeFormat#CODE_128}
|
||||
*
|
||||
* @return
|
||||
* @return 默认支持的格式
|
||||
*/
|
||||
private static List<BarcodeFormat> getDefaultFormats() {
|
||||
List<BarcodeFormat> list = new ArrayList<>();
|
||||
@ -167,7 +172,7 @@ public final class DecodeFormatManager {
|
||||
* 支持解码的格式
|
||||
*
|
||||
* @param barcodeFormats {@link BarcodeFormat}
|
||||
* @return
|
||||
* @return 返回添加了通用配置后的解码支持类型与配置
|
||||
*/
|
||||
public static Map<DecodeHintType, Object> createDecodeHints(@NonNull BarcodeFormat... barcodeFormats) {
|
||||
Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
|
||||
@ -179,7 +184,7 @@ public final class DecodeFormatManager {
|
||||
* 支持解码的格式
|
||||
*
|
||||
* @param barcodeFormat {@link BarcodeFormat}
|
||||
* @return
|
||||
* @return 返回添加了通用配置后的解码支持类型与配置
|
||||
*/
|
||||
public static Map<DecodeHintType, Object> createDecodeHint(@NonNull BarcodeFormat barcodeFormat) {
|
||||
Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
|
||||
@ -188,8 +193,9 @@ public final class DecodeFormatManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hints
|
||||
* @param formats
|
||||
* 为解码配置添加一些通用配置
|
||||
* @param hints 解码支持类型与配置
|
||||
* @param formats 需要支持的解码格式
|
||||
*/
|
||||
private static void addDecodeHintTypes(Map<DecodeHintType, Object> hints, List<BarcodeFormat> formats) {
|
||||
// Image is known to be of one of a few possible formats.
|
||||
|
||||
@ -15,6 +15,8 @@ import androidx.annotation.Nullable;
|
||||
* 矩阵区域分析器:主要用于锁定具体的识别区域
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
public abstract class AreaRectAnalyzer extends ImageAnalyzer {
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.king.zxing.analyze;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.LuminanceSource;
|
||||
@ -8,17 +10,17 @@ import com.google.zxing.Reader;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.GlobalHistogramBinarizer;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import com.king.camera.scan.util.LogUtils;
|
||||
import com.king.logx.LogX;
|
||||
import com.king.zxing.DecodeConfig;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* 条码分析器
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class BarcodeFormatAnalyzer extends AreaRectAnalyzer {
|
||||
@ -65,9 +67,9 @@ public abstract class BarcodeFormatAnalyzer extends AreaRectAnalyzer {
|
||||
}
|
||||
if (rawResult != null) {
|
||||
long end = System.currentTimeMillis();
|
||||
LogUtils.d("Found barcode in " + (end - start) + " ms");
|
||||
LogX.d("Found barcode in " + (end - start) + " ms");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ignored) {
|
||||
|
||||
} finally {
|
||||
mReader.reset();
|
||||
@ -82,14 +84,14 @@ public abstract class BarcodeFormatAnalyzer extends AreaRectAnalyzer {
|
||||
try {
|
||||
//采用HybridBinarizer解析
|
||||
result = mReader.decode(new BinaryBitmap(new HybridBinarizer(source)), mHints);
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
if (isMultiDecode && result == null) {
|
||||
//如果没有解析成功,再采用GlobalHistogramBinarizer解析一次
|
||||
result = mReader.decode(new BinaryBitmap(new GlobalHistogramBinarizer(source)), mHints);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return result;
|
||||
|
||||
@ -20,6 +20,8 @@ import androidx.camera.core.ImageProxy;
|
||||
* 图像分析器
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
public abstract class ImageAnalyzer implements Analyzer<Result> {
|
||||
|
||||
@ -46,10 +48,11 @@ public abstract class ImageAnalyzer implements Analyzer<Result> {
|
||||
queue.add(bytes);
|
||||
joinQueue.set(true);
|
||||
}
|
||||
if (queue.isEmpty()) {
|
||||
|
||||
final byte[] nv21Data = queue.poll();
|
||||
if(nv21Data == null) {
|
||||
return;
|
||||
}
|
||||
final byte[] nv21Data = queue.poll();
|
||||
|
||||
try {
|
||||
int rotation = imageProxy.getImageInfo().getRotationDegrees();
|
||||
|
||||
@ -8,7 +8,7 @@ import com.google.zxing.PlanarYUVLuminanceSource;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.GlobalHistogramBinarizer;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import com.king.camera.scan.util.LogUtils;
|
||||
import com.king.logx.LogX;
|
||||
import com.king.zxing.DecodeConfig;
|
||||
|
||||
import java.util.Map;
|
||||
@ -19,6 +19,8 @@ import androidx.annotation.Nullable;
|
||||
* 多格式分析器:主要用于分析识别条形码/二维码
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class MultiFormatAnalyzer extends AreaRectAnalyzer {
|
||||
@ -69,9 +71,9 @@ public class MultiFormatAnalyzer extends AreaRectAnalyzer {
|
||||
}
|
||||
if (rawResult != null) {
|
||||
long end = System.currentTimeMillis();
|
||||
LogUtils.d("Found barcode in " + (end - start) + " ms");
|
||||
LogX.d("Found barcode in " + (end - start) + " ms");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ignored) {
|
||||
|
||||
} finally {
|
||||
mReader.reset();
|
||||
@ -86,14 +88,14 @@ public class MultiFormatAnalyzer extends AreaRectAnalyzer {
|
||||
try {
|
||||
// 采用HybridBinarizer解析
|
||||
result = mReader.decodeWithState(new BinaryBitmap(new HybridBinarizer(source)));
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
if (isMultiDecode && result == null) {
|
||||
// 如果没有解析成功,再采用GlobalHistogramBinarizer解析一次
|
||||
result = mReader.decodeWithState(new BinaryBitmap(new GlobalHistogramBinarizer(source)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return result;
|
||||
|
||||
@ -14,6 +14,8 @@ import androidx.annotation.Nullable;
|
||||
* 二维码分析器
|
||||
*
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class QRCodeAnalyzer extends BarcodeFormatAnalyzer {
|
||||
|
||||
@ -20,13 +20,13 @@ import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.FloatRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
@ -37,13 +37,12 @@ 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.GlobalHistogramBinarizer;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import com.google.zxing.qrcode.QRCodeWriter;
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
import com.king.camera.scan.util.LogUtils;
|
||||
import com.king.logx.LogX;
|
||||
import com.king.zxing.DecodeFormatManager;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -52,7 +51,9 @@ import java.util.Map;
|
||||
/**
|
||||
* 二维码/条形码工具类:主要包括二维码/条形码的解析与生成
|
||||
*
|
||||
* @author Jenly <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
|
||||
* <p>
|
||||
* <a href="https://github.com/jenly1314">Follow me</a>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public final class CodeUtils {
|
||||
@ -67,61 +68,61 @@ public final class CodeUtils {
|
||||
/**
|
||||
* 生成二维码
|
||||
*
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @param content 二维码的内容
|
||||
* @param size 二维码的大小
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(String content, int heightPix) {
|
||||
return createQRCode(content, heightPix, null);
|
||||
public static Bitmap createQRCode(@NonNull String content, int size) {
|
||||
return createQRCode(content, size, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码
|
||||
*
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @param size 二维码的大小
|
||||
* @param codeColor 二维码的颜色
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(String content, int heightPix, int codeColor) {
|
||||
return createQRCode(content, heightPix, null, codeColor);
|
||||
public static Bitmap createQRCode(@NonNull String content, int size, @ColorInt int codeColor) {
|
||||
return createQRCode(content, size, null, codeColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成我二维码
|
||||
*
|
||||
* @param content 二维码的内容
|
||||
* @param size 二维码的大小
|
||||
* @param logo Logo大小默认占二维码的20%
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(@NonNull String content, int size, @Nullable Bitmap logo) {
|
||||
return createQRCode(content, size, logo, Color.BLACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成我二维码
|
||||
*
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @param logo logo大小默认占二维码的20%
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo) {
|
||||
return createQRCode(content, heightPix, logo, Color.BLACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成我二维码
|
||||
*
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @param logo logo大小默认占二维码的20%
|
||||
* @param size 二维码的大小
|
||||
* @param logo Logo大小默认占二维码的20%
|
||||
* @param codeColor 二维码的颜色
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo, int codeColor) {
|
||||
return createQRCode(content, heightPix, logo, 0.2f, codeColor);
|
||||
public static Bitmap createQRCode(@NonNull String content, int size, @Nullable Bitmap logo, @ColorInt int codeColor) {
|
||||
return createQRCode(content, size, logo, 0.2f, codeColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码
|
||||
*
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @param logo 二维码中间的logo
|
||||
* @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||
* @param content 二维码的内容
|
||||
* @param size 二维码的大小
|
||||
* @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) {
|
||||
public static Bitmap createQRCode(@NonNull String content, int size, @Nullable Bitmap logo, @FloatRange(from = 0.0f, to = 1.0f) float ratio) {
|
||||
//配置参数
|
||||
Map<EncodeHintType, Object> hints = new HashMap<>();
|
||||
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
|
||||
@ -129,66 +130,66 @@ public final class CodeUtils {
|
||||
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
|
||||
//设置空白边距的宽度
|
||||
hints.put(EncodeHintType.MARGIN, 1); //default is 4
|
||||
return createQRCode(content, heightPix, logo, ratio, hints);
|
||||
return createQRCode(content, size, logo, ratio, hints);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码
|
||||
*
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @param logo 二维码中间的logo
|
||||
* @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||
* @param size 二维码的大小
|
||||
* @param logo 二维码中间的Logo
|
||||
* @param ratio Logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||
* @param codeColor 二维码的颜色
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo, @FloatRange(from = 0.0f, to = 1.0f) float ratio, int codeColor) {
|
||||
public static Bitmap createQRCode(@NonNull String content, int size, @Nullable Bitmap logo, @FloatRange(from = 0.0f, to = 1.0f) float ratio, @ColorInt int codeColor) {
|
||||
//配置参数
|
||||
Map<EncodeHintType, Object> hints = new HashMap<>();
|
||||
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
|
||||
//容错级别
|
||||
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
|
||||
//设置空白边距的宽度
|
||||
hints.put(EncodeHintType.MARGIN, 1); //default is 1
|
||||
return createQRCode(content, heightPix, logo, ratio, hints, codeColor);
|
||||
hints.put(EncodeHintType.MARGIN, 1); //default is 4
|
||||
return createQRCode(content, size, logo, ratio, hints, codeColor);
|
||||
}
|
||||
|
||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo, @FloatRange(from = 0.0f, to = 1.0f) float ratio, Map<EncodeHintType, ?> hints) {
|
||||
return createQRCode(content, heightPix, logo, ratio, hints, Color.BLACK);
|
||||
public static Bitmap createQRCode(@NonNull String content, int size, @Nullable Bitmap logo, @FloatRange(from = 0.0f, to = 1.0f) float ratio, @Nullable Map<EncodeHintType, ?> hints) {
|
||||
return createQRCode(content, size, logo, ratio, hints, Color.BLACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成二维码
|
||||
*
|
||||
* @param content 二维码的内容
|
||||
* @param heightPix 二维码的高
|
||||
* @param logo 二维码中间的logo
|
||||
* @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||
* @param size 二维码的大小
|
||||
* @param logo 二维码中间的Logo
|
||||
* @param ratio Logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||
* @param hints
|
||||
* @param codeColor 二维码的颜色
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createQRCode(String content, int heightPix, Bitmap logo, @FloatRange(from = 0.0f, to = 1.0f) float ratio, Map<EncodeHintType, ?> hints, int codeColor) {
|
||||
public static Bitmap createQRCode(@NonNull String content, int size, @Nullable Bitmap logo, @FloatRange(from = 0.0f, to = 1.0f) float ratio, @Nullable Map<EncodeHintType, ?> hints, @ColorInt int codeColor) {
|
||||
try {
|
||||
|
||||
// 图像数据转换,使用了矩阵转换
|
||||
BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, heightPix, heightPix, hints);
|
||||
int[] pixels = new int[heightPix * heightPix];
|
||||
BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
|
||||
int[] pixels = new int[size * size];
|
||||
// 下面这里按照二维码的算法,逐个生成二维码的图片,
|
||||
// 两个for循环是图片横列扫描的结果
|
||||
for (int y = 0; y < heightPix; y++) {
|
||||
for (int x = 0; x < heightPix; x++) {
|
||||
for (int y = 0; y < size; y++) {
|
||||
for (int x = 0; x < size; x++) {
|
||||
if (bitMatrix.get(x, y)) {
|
||||
pixels[y * heightPix + x] = codeColor;
|
||||
pixels[y * size + x] = codeColor;
|
||||
} else {
|
||||
pixels[y * heightPix + x] = Color.WHITE;
|
||||
pixels[y * size + x] = Color.WHITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 生成二维码图片的格式
|
||||
Bitmap bitmap = Bitmap.createBitmap(heightPix, heightPix, Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, heightPix, 0, 0, heightPix, heightPix);
|
||||
Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, size, 0, 0, size, size);
|
||||
|
||||
if (logo != null) {
|
||||
bitmap = addLogo(bitmap, logo, ratio);
|
||||
@ -196,7 +197,7 @@ public final class CodeUtils {
|
||||
|
||||
return bitmap;
|
||||
} catch (Exception e) {
|
||||
LogUtils.w(e.getMessage());
|
||||
LogX.w(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -205,12 +206,12 @@ public final class CodeUtils {
|
||||
/**
|
||||
* 在二维码中间添加Logo图案
|
||||
*
|
||||
* @param src
|
||||
* @param logo
|
||||
* @param ratio logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||
* @param src 原图
|
||||
* @param logo 中间的Logo
|
||||
* @param ratio Logo所占比例 因为二维码的最大容错率为30%,所以建议ratio的范围小于0.3
|
||||
* @return
|
||||
*/
|
||||
private static Bitmap addLogo(Bitmap src, Bitmap logo, @FloatRange(from = 0.0f, to = 1.0f) float ratio) {
|
||||
private static Bitmap addLogo(@Nullable Bitmap src, @Nullable Bitmap logo, @FloatRange(from = 0.0f, to = 1.0f) float ratio) {
|
||||
if (src == null) {
|
||||
return null;
|
||||
}
|
||||
@ -240,13 +241,13 @@ public final class CodeUtils {
|
||||
bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
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.scale(scaleFactor, scaleFactor, srcWidth / 2f, srcHeight / 2f);
|
||||
canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2f, (srcHeight - logoHeight) / 2f, null);
|
||||
canvas.save();
|
||||
canvas.restore();
|
||||
} catch (Exception e) {
|
||||
bitmap = null;
|
||||
LogUtils.w(e.getMessage());
|
||||
LogX.w(e);
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
@ -258,7 +259,8 @@ public final class CodeUtils {
|
||||
* @param bitmapPath 需要解析的图片路径
|
||||
* @return
|
||||
*/
|
||||
public static String parseQRCode(String bitmapPath) {
|
||||
@Nullable
|
||||
public static String parseQRCode(@NonNull String bitmapPath) {
|
||||
Result result = parseQRCodeResult(bitmapPath);
|
||||
if (result != null) {
|
||||
return result.getText();
|
||||
@ -272,7 +274,8 @@ public final class CodeUtils {
|
||||
* @param bitmapPath 需要解析的图片路径
|
||||
* @return
|
||||
*/
|
||||
public static Result parseQRCodeResult(String bitmapPath) {
|
||||
@Nullable
|
||||
public static Result parseQRCodeResult(@NonNull String bitmapPath) {
|
||||
return parseQRCodeResult(bitmapPath, DEFAULT_REQ_WIDTH, DEFAULT_REQ_HEIGHT);
|
||||
}
|
||||
|
||||
@ -284,7 +287,8 @@ public final class CodeUtils {
|
||||
* @param reqHeight 请求目标高度,如果实际图片高度大于此值,会自动进行压缩处理,当 reqWidth 和 reqHeight都小于或等于0时,则不进行压缩处理
|
||||
* @return
|
||||
*/
|
||||
public static Result parseQRCodeResult(String bitmapPath, int reqWidth, int reqHeight) {
|
||||
@Nullable
|
||||
public static Result parseQRCodeResult(@NonNull String bitmapPath, int reqWidth, int reqHeight) {
|
||||
return parseCodeResult(bitmapPath, reqWidth, reqHeight, DecodeFormatManager.QR_CODE_HINTS);
|
||||
}
|
||||
|
||||
@ -294,7 +298,8 @@ public final class CodeUtils {
|
||||
* @param bitmapPath 需要解析的图片路径
|
||||
* @return
|
||||
*/
|
||||
public static String parseCode(String bitmapPath) {
|
||||
@Nullable
|
||||
public static String parseCode(@NonNull String bitmapPath) {
|
||||
return parseCode(bitmapPath, DecodeFormatManager.ALL_HINTS);
|
||||
}
|
||||
|
||||
@ -305,7 +310,8 @@ public final class CodeUtils {
|
||||
* @param hints 解析编码类型
|
||||
* @return
|
||||
*/
|
||||
public static String parseCode(String bitmapPath, Map<DecodeHintType, Object> hints) {
|
||||
@Nullable
|
||||
public static String parseCode(@NonNull String bitmapPath, @Nullable Map<DecodeHintType, Object> hints) {
|
||||
Result result = parseCodeResult(bitmapPath, hints);
|
||||
if (result != null) {
|
||||
return result.getText();
|
||||
@ -319,7 +325,8 @@ public final class CodeUtils {
|
||||
* @param bitmap 解析的图片
|
||||
* @return
|
||||
*/
|
||||
public static String parseQRCode(Bitmap bitmap) {
|
||||
@Nullable
|
||||
public static String parseQRCode(@NonNull Bitmap bitmap) {
|
||||
return parseCode(bitmap, DecodeFormatManager.QR_CODE_HINTS);
|
||||
}
|
||||
|
||||
@ -329,7 +336,8 @@ public final class CodeUtils {
|
||||
* @param bitmap 解析的图片
|
||||
* @return
|
||||
*/
|
||||
public static String parseCode(Bitmap bitmap) {
|
||||
@Nullable
|
||||
public static String parseCode(@NonNull Bitmap bitmap) {
|
||||
return parseCode(bitmap, DecodeFormatManager.ALL_HINTS);
|
||||
}
|
||||
|
||||
@ -340,7 +348,8 @@ public final class CodeUtils {
|
||||
* @param hints 解析编码类型
|
||||
* @return
|
||||
*/
|
||||
public static String parseCode(Bitmap bitmap, Map<DecodeHintType, Object> hints) {
|
||||
@Nullable
|
||||
public static String parseCode(@NonNull Bitmap bitmap, @Nullable Map<DecodeHintType, Object> hints) {
|
||||
Result result = parseCodeResult(bitmap, hints);
|
||||
if (result != null) {
|
||||
return result.getText();
|
||||
@ -355,7 +364,8 @@ public final class CodeUtils {
|
||||
* @param hints 解析编码类型
|
||||
* @return
|
||||
*/
|
||||
public static Result parseCodeResult(String bitmapPath, Map<DecodeHintType, Object> hints) {
|
||||
@Nullable
|
||||
public static Result parseCodeResult(@NonNull String bitmapPath, @Nullable Map<DecodeHintType, Object> hints) {
|
||||
return parseCodeResult(bitmapPath, DEFAULT_REQ_WIDTH, DEFAULT_REQ_HEIGHT, hints);
|
||||
}
|
||||
|
||||
@ -368,7 +378,8 @@ public final class CodeUtils {
|
||||
* @param hints 解析编码类型
|
||||
* @return
|
||||
*/
|
||||
public static Result parseCodeResult(String bitmapPath, int reqWidth, int reqHeight, Map<DecodeHintType, Object> hints) {
|
||||
@Nullable
|
||||
public static Result parseCodeResult(@NonNull String bitmapPath, int reqWidth, int reqHeight, @Nullable Map<DecodeHintType, Object> hints) {
|
||||
return parseCodeResult(compressBitmap(bitmapPath, reqWidth, reqHeight), hints);
|
||||
}
|
||||
|
||||
@ -378,7 +389,8 @@ public final class CodeUtils {
|
||||
* @param bitmap 解析的图片
|
||||
* @return
|
||||
*/
|
||||
public static Result parseCodeResult(Bitmap bitmap) {
|
||||
@Nullable
|
||||
public static Result parseCodeResult(@NonNull Bitmap bitmap) {
|
||||
return parseCodeResult(getRGBLuminanceSource(bitmap), DecodeFormatManager.ALL_HINTS);
|
||||
}
|
||||
|
||||
@ -389,7 +401,8 @@ public final class CodeUtils {
|
||||
* @param hints 解析编码类型
|
||||
* @return
|
||||
*/
|
||||
public static Result parseCodeResult(Bitmap bitmap, Map<DecodeHintType, Object> hints) {
|
||||
@Nullable
|
||||
public static Result parseCodeResult(@NonNull Bitmap bitmap, @Nullable Map<DecodeHintType, Object> hints) {
|
||||
return parseCodeResult(getRGBLuminanceSource(bitmap), hints);
|
||||
}
|
||||
|
||||
@ -400,7 +413,8 @@ public final class CodeUtils {
|
||||
* @param hints
|
||||
* @return
|
||||
*/
|
||||
public static Result parseCodeResult(LuminanceSource source, Map<DecodeHintType, Object> hints) {
|
||||
@Nullable
|
||||
public static Result parseCodeResult(LuminanceSource source, @Nullable Map<DecodeHintType, Object> hints) {
|
||||
Result result = null;
|
||||
MultiFormatReader reader = new MultiFormatReader();
|
||||
try {
|
||||
@ -416,7 +430,7 @@ public final class CodeUtils {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtils.w(e.getMessage());
|
||||
LogX.w(e);
|
||||
} finally {
|
||||
reader.reset();
|
||||
}
|
||||
@ -424,20 +438,21 @@ public final class CodeUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Result decodeInternal(MultiFormatReader reader, LuminanceSource source) {
|
||||
Result result = null;
|
||||
try {
|
||||
try {
|
||||
//采用HybridBinarizer解析
|
||||
result = reader.decodeWithState(new BinaryBitmap(new HybridBinarizer(source)));
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
if (result == null) {
|
||||
//如果没有解析成功,再采用GlobalHistogramBinarizer解析一次
|
||||
result = reader.decodeWithState(new BinaryBitmap(new GlobalHistogramBinarizer(source)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return result;
|
||||
@ -450,28 +465,14 @@ public final class CodeUtils {
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private static Bitmap compressBitmap(String path, int reqWidth, int reqHeight) {
|
||||
private static Bitmap compressBitmap(@NonNull String path, int reqWidth, int reqHeight) {
|
||||
if (reqWidth > 0 && reqHeight > 0) {//都大于进行判断是否压缩
|
||||
|
||||
BitmapFactory.Options newOpts = new BitmapFactory.Options();
|
||||
// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
|
||||
newOpts.inJustDecodeBounds = true;//获取原始图片大小
|
||||
BitmapFactory.decodeFile(path, newOpts);// 此时返回bm为空
|
||||
float width = newOpts.outWidth;
|
||||
float height = newOpts.outHeight;
|
||||
// 缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
|
||||
int wSize = 1;// wSize=1表示不缩放
|
||||
if (width > reqWidth) {// 如果宽度大的话根据宽度固定大小缩放
|
||||
wSize = (int) (width / reqWidth);
|
||||
}
|
||||
int hSize = 1;// wSize=1表示不缩放
|
||||
if (height > reqHeight) {// 如果高度高的话根据宽度固定大小缩放
|
||||
hSize = (int) (height / reqHeight);
|
||||
}
|
||||
int size = Math.max(wSize, hSize);
|
||||
if (size <= 0)
|
||||
size = 1;
|
||||
newOpts.inSampleSize = size;// 设置缩放比例
|
||||
newOpts.inSampleSize = getSampleSize(reqWidth, reqHeight, newOpts);
|
||||
// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
|
||||
newOpts.inJustDecodeBounds = false;
|
||||
|
||||
@ -482,6 +483,30 @@ public final class CodeUtils {
|
||||
return BitmapFactory.decodeFile(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reqWidth
|
||||
* @param reqHeight
|
||||
* @param newOpts
|
||||
* @return
|
||||
*/
|
||||
private static int getSampleSize(int reqWidth, int reqHeight,@NonNull BitmapFactory.Options newOpts) {
|
||||
float width = newOpts.outWidth;
|
||||
float height = newOpts.outHeight;
|
||||
// 缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
|
||||
int wSize = 1;// wSize=1表示不缩放
|
||||
if (width > reqWidth) {// 如果宽度大的话根据宽度固定大小缩放
|
||||
wSize = (int) (width / reqWidth);
|
||||
}
|
||||
int hSize = 1;// wSize=1表示不缩放
|
||||
if (height > reqHeight) {// 如果高度高的话根据宽度固定大小缩放
|
||||
hSize = (int) (height / reqHeight);
|
||||
}
|
||||
int size = Math.max(wSize, hSize);
|
||||
if (size <= 0)
|
||||
size = 1;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取RGBLuminanceSource
|
||||
@ -507,7 +532,7 @@ public final class CodeUtils {
|
||||
* @param desiredHeight
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createBarCode(String content, int desiredWidth, int desiredHeight) {
|
||||
public static Bitmap createBarCode(@NonNull String content, int desiredWidth, int desiredHeight) {
|
||||
return createBarCode(content, BarcodeFormat.CODE_128, desiredWidth, desiredHeight, null);
|
||||
}
|
||||
|
||||
@ -520,11 +545,11 @@ public final class CodeUtils {
|
||||
* @param desiredHeight
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createBarCode(String content, BarcodeFormat format, int desiredWidth, int desiredHeight) {
|
||||
public static Bitmap createBarCode(@NonNull String content, @NonNull BarcodeFormat format, int desiredWidth, int desiredHeight) {
|
||||
return createBarCode(content, format, desiredWidth, desiredHeight, null);
|
||||
}
|
||||
|
||||
public static Bitmap createBarCode(String content, int desiredWidth, int desiredHeight, boolean isShowText) {
|
||||
public static Bitmap createBarCode(@NonNull String content, int desiredWidth, int desiredHeight, boolean isShowText) {
|
||||
return createBarCode(content, BarcodeFormat.CODE_128, desiredWidth, desiredHeight, null, isShowText, 40, Color.BLACK);
|
||||
}
|
||||
|
||||
@ -538,7 +563,7 @@ public final class CodeUtils {
|
||||
* @param codeColor
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createBarCode(String content, int desiredWidth, int desiredHeight, boolean isShowText, @ColorInt int codeColor) {
|
||||
public static Bitmap createBarCode(@NonNull String content, int desiredWidth, int desiredHeight, boolean isShowText, @ColorInt int codeColor) {
|
||||
return createBarCode(content, BarcodeFormat.CODE_128, desiredWidth, desiredHeight, null, isShowText, 40, codeColor);
|
||||
}
|
||||
|
||||
@ -552,7 +577,7 @@ public final class CodeUtils {
|
||||
* @param hints
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createBarCode(String content, BarcodeFormat format, int desiredWidth, int desiredHeight, Map<EncodeHintType, ?> hints) {
|
||||
public static Bitmap createBarCode(@NonNull String content, @NonNull BarcodeFormat format, int desiredWidth, int desiredHeight, @Nullable Map<EncodeHintType, ?> hints) {
|
||||
return createBarCode(content, format, desiredWidth, desiredHeight, hints, false, 40, Color.BLACK);
|
||||
}
|
||||
|
||||
@ -567,7 +592,7 @@ public final class CodeUtils {
|
||||
* @param isShowText
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createBarCode(String content, BarcodeFormat format, int desiredWidth, int desiredHeight, Map<EncodeHintType, ?> hints, boolean isShowText) {
|
||||
public static Bitmap createBarCode(@NonNull String content, @NonNull BarcodeFormat format, int desiredWidth, int desiredHeight, @Nullable Map<EncodeHintType, ?> hints, boolean isShowText) {
|
||||
return createBarCode(content, format, desiredWidth, desiredHeight, hints, isShowText, 40, Color.BLACK);
|
||||
}
|
||||
|
||||
@ -582,7 +607,7 @@ public final class CodeUtils {
|
||||
* @param codeColor
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createBarCode(String content, BarcodeFormat format, int desiredWidth, int desiredHeight, boolean isShowText, @ColorInt int codeColor) {
|
||||
public static Bitmap createBarCode(@NonNull String content, @NonNull BarcodeFormat format, int desiredWidth, int desiredHeight, boolean isShowText, @ColorInt int codeColor) {
|
||||
return createBarCode(content, format, desiredWidth, desiredHeight, null, isShowText, 40, codeColor);
|
||||
}
|
||||
|
||||
@ -597,7 +622,7 @@ public final class CodeUtils {
|
||||
* @param isShowText
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createBarCode(String content, BarcodeFormat format, int desiredWidth, int desiredHeight, Map<EncodeHintType, ?> hints, boolean isShowText, @ColorInt int codeColor) {
|
||||
public static Bitmap createBarCode(@NonNull String content, @NonNull BarcodeFormat format, int desiredWidth, int desiredHeight, @Nullable Map<EncodeHintType, ?> hints, boolean isShowText, @ColorInt int codeColor) {
|
||||
return createBarCode(content, format, desiredWidth, desiredHeight, hints, isShowText, 40, codeColor);
|
||||
}
|
||||
|
||||
@ -614,12 +639,11 @@ public final class CodeUtils {
|
||||
* @param codeColor
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap createBarCode(String content, BarcodeFormat format, int desiredWidth, int desiredHeight, Map<EncodeHintType, ?> hints, boolean isShowText, int textSize, @ColorInt int codeColor) {
|
||||
public static Bitmap createBarCode(@NonNull String content, @NonNull BarcodeFormat format, int desiredWidth, int desiredHeight, @Nullable Map<EncodeHintType, ?> hints, boolean isShowText, int textSize, @ColorInt int codeColor) {
|
||||
if (TextUtils.isEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
final int WHITE = Color.WHITE;
|
||||
final int BLACK = codeColor;
|
||||
|
||||
MultiFormatWriter writer = new MultiFormatWriter();
|
||||
try {
|
||||
@ -632,7 +656,7 @@ public final class CodeUtils {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int offset = y * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
|
||||
pixels[offset + x] = result.get(x, y) ? codeColor : WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -643,8 +667,8 @@ public final class CodeUtils {
|
||||
return addCode(bitmap, content, textSize, codeColor, textSize / 2);
|
||||
}
|
||||
return bitmap;
|
||||
} catch (WriterException e) {
|
||||
LogUtils.w(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
LogX.w(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -658,7 +682,7 @@ public final class CodeUtils {
|
||||
* @param textColor
|
||||
* @return
|
||||
*/
|
||||
private static Bitmap addCode(Bitmap src, String code, int textSize, @ColorInt int textColor, int offset) {
|
||||
private static Bitmap addCode(@Nullable Bitmap src, @Nullable String code, int textSize, @ColorInt int textColor, int offset) {
|
||||
if (src == null) {
|
||||
return null;
|
||||
}
|
||||
@ -684,12 +708,12 @@ public final class CodeUtils {
|
||||
paint.setTextSize(textSize);
|
||||
paint.setColor(textColor);
|
||||
paint.setTextAlign(Paint.Align.CENTER);
|
||||
canvas.drawText(code, srcWidth / 2, srcHeight + textSize / 2 + offset, paint);
|
||||
canvas.drawText(code, srcWidth / 2f, srcHeight + textSize / 2f + offset, paint);
|
||||
canvas.save();
|
||||
canvas.restore();
|
||||
} catch (Exception e) {
|
||||
bitmap = null;
|
||||
LogUtils.w(e.getMessage());
|
||||
LogX.w(e);
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
|
||||
Reference in New Issue
Block a user