发布v3.2.0

This commit is contained in:
Jenly
2024-07-16 23:36:33 +08:00
parent 78b59b2dbc
commit 5774a41811
23 changed files with 239 additions and 160 deletions

View File

@ -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.02024-07-16
* 更新CameraScan至v1.2.0
* 更新ViewfinderView至v1.2.0
* 优化细节
#### v3.1.12024-04-29
* 更新CameraScan至v1.1.1
* 更新zxing至v3.5.3

View File

@ -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.

View File

@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 41,
"versionName": "3.1.1",
"versionCode": 42,
"versionName": "3.2.0",
"outputFile": "app-release.apk"
}
],

View File

@ -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 {

View File

@ -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() {

View File

@ -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);
});

View File

@ -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() {

View File

@ -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);
}
/**

View File

@ -1,5 +1,10 @@
## 版本记录
#### v3.2.02024-07-16
* 更新CameraScan至v1.2.0
* 更新ViewfinderView至v1.2.0
* 优化细节
#### v3.1.12024-04-29
* 更新CameraScan至v1.1.1
* 更新zxing至v3.5.3

View File

@ -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

View File

@ -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"

View File

@ -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 {

View File

@ -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> {

View File

@ -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> {

View File

@ -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{" +

View File

@ -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.

View File

@ -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 {

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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 {

View File

@ -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;