diff --git a/README.md b/README.md index 31c2996..3f8376b 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/app/build.gradle b/app/build.gradle index 1556d96..8786755 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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 diff --git a/app/release/app-release.apk b/app/release/app-release.apk index af5aa06..bf8ad99 100644 Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 0fc7711..5cd5427 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "attributes": [], - "versionCode": 41, - "versionName": "3.1.1", + "versionCode": 42, + "versionName": "3.2.0", "outputFile": "app-release.apk" } ], diff --git a/app/src/main/java/com/king/zxing/app/CodeActivity.java b/app/src/main/java/com/king/zxing/app/CodeActivity.java index cc42f19..e26d053 100644 --- a/app/src/main/java/com/king/zxing/app/CodeActivity.java +++ b/app/src/main/java/com/king/zxing/app/CodeActivity.java @@ -33,7 +33,10 @@ import androidx.appcompat.app.AppCompatActivity; /** * 生成条形码/二维码示例 - * @author Jenly Jenly + * + * @author Jenly + *

+ * Follow me */ public class CodeActivity extends AppCompatActivity { diff --git a/app/src/main/java/com/king/zxing/app/FullScreenQRCodeScanActivity.kt b/app/src/main/java/com/king/zxing/app/FullScreenQRCodeScanActivity.kt index ca29ca3..f047d50 100644 --- a/app/src/main/java/com/king/zxing/app/FullScreenQRCodeScanActivity.kt +++ b/app/src/main/java/com/king/zxing/app/FullScreenQRCodeScanActivity.kt @@ -16,7 +16,10 @@ import com.king.zxing.analyze.QRCodeAnalyzer /** * 扫二维码全屏识别示例 + * * @author Jenly + *

+ * Follow me */ class FullScreenQRCodeScanActivity : BarcodeCameraScanActivity() { diff --git a/app/src/main/java/com/king/zxing/app/MainActivity.java b/app/src/main/java/com/king/zxing/app/MainActivity.java index cb5dbce..93c02d3 100644 --- a/app/src/main/java/com/king/zxing/app/MainActivity.java +++ b/app/src/main/java/com/king/zxing/app/MainActivity.java @@ -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 Jenly + *

+ * Follow me */ 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); }); diff --git a/app/src/main/java/com/king/zxing/app/MultiFormatScanActivity.kt b/app/src/main/java/com/king/zxing/app/MultiFormatScanActivity.kt index 2b0d21a..3cbab9e 100644 --- a/app/src/main/java/com/king/zxing/app/MultiFormatScanActivity.kt +++ b/app/src/main/java/com/king/zxing/app/MultiFormatScanActivity.kt @@ -11,7 +11,10 @@ import com.king.zxing.analyze.MultiFormatAnalyzer /** * 连续扫码(识别多种格式)示例 + * * @author Jenly + *

+ * Follow me */ class MultiFormatScanActivity : BarcodeCameraScanActivity() { diff --git a/app/src/main/java/com/king/zxing/app/QRCodeScanActivity.java b/app/src/main/java/com/king/zxing/app/QRCodeScanActivity.java index 88bf074..dce551f 100644 --- a/app/src/main/java/com/king/zxing/app/QRCodeScanActivity.java +++ b/app/src/main/java/com/king/zxing/app/QRCodeScanActivity.java @@ -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 Jenly + *

+ * Follow me */ 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); } /** diff --git a/change_log.md b/change_log.md index 9b47e3e..f6f26ad 100644 --- a/change_log.md +++ b/change_log.md @@ -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 diff --git a/gradle.properties b/gradle.properties index eaadf95..4931de3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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 diff --git a/versions.gradle b/versions.gradle index ddac4b0..db0c467 100644 --- a/versions.gradle +++ b/versions.gradle @@ -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" diff --git a/zxing-lite/build.gradle b/zxing-lite/build.gradle index 73e1d4d..619ef95 100644 --- a/zxing-lite/build.gradle +++ b/zxing-lite/build.gradle @@ -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 { diff --git a/zxing-lite/src/main/java/com/king/zxing/BarcodeCameraScanActivity.java b/zxing-lite/src/main/java/com/king/zxing/BarcodeCameraScanActivity.java index d9ce40f..d9c913f 100644 --- a/zxing-lite/src/main/java/com/king/zxing/BarcodeCameraScanActivity.java +++ b/zxing-lite/src/main/java/com/king/zxing/BarcodeCameraScanActivity.java @@ -16,6 +16,8 @@ import androidx.annotation.Nullable; * 通过继承 {@link BarcodeCameraScanActivity}或{@link BarcodeCameraScanFragment}可快速实现扫码识别 * * @author Jenly + *

+ * Follow me */ public abstract class BarcodeCameraScanActivity extends BaseCameraScanActivity { diff --git a/zxing-lite/src/main/java/com/king/zxing/BarcodeCameraScanFragment.java b/zxing-lite/src/main/java/com/king/zxing/BarcodeCameraScanFragment.java index be89a28..b69d4a6 100644 --- a/zxing-lite/src/main/java/com/king/zxing/BarcodeCameraScanFragment.java +++ b/zxing-lite/src/main/java/com/king/zxing/BarcodeCameraScanFragment.java @@ -16,6 +16,8 @@ import androidx.annotation.Nullable; * 通过继承 {@link BarcodeCameraScanActivity}或{@link BarcodeCameraScanFragment}可快速实现扫码识别 * * @author Jenly + *

+ * Follow me */ public abstract class BarcodeCameraScanFragment extends BaseCameraScanFragment { diff --git a/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java b/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java index 00ab030..7e771ff 100644 --- a/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java +++ b/zxing-lite/src/main/java/com/king/zxing/DecodeConfig.java @@ -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; - /** * 解码配置:主要用于在扫码识别时,提供一些配置,便于扩展。通过配置可决定内置分析器的能力,从而间接的控制并简化扫码识别的流程 *

@@ -25,7 +26,6 @@ import androidx.annotation.FloatRange; * {@link DecodeFormatManager#DEFAULT_HINTS} *

* - * @author Jenly *

* 如果不满足您也可以通过{@link DecodeFormatManager#createDecodeHints(BarcodeFormat...)}自己配置支持的格式 * @@ -38,7 +38,11 @@ import androidx.annotation.FloatRange; * 因为{@link androidx.camera.view.PreviewView}的预览区域是经过裁剪的,所以这里的区域并不是用户所能预览到的区域,而是指Camera预览的真实区域, *

* 即判定区域分析的优先级顺序为:{@link #setFullAreaScan(boolean)} -> {@link #setAnalyzeAreaRect(Rect)} -> {@link #setAreaRectRatio(float)} - *

+ *

+ * + * @author Jenly + *

+ * Follow me */ @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{" + diff --git a/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java b/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java index f3bc97c..6e5a1c4 100644 --- a/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java +++ b/zxing-lite/src/main/java/com/king/zxing/DecodeFormatManager.java @@ -18,11 +18,13 @@ import androidx.annotation.NonNull; * 将常见的一些解码配置已根据条形码类型进行了几大划分,可根据需要找到符合的划分配置类型直接使用。 * * @author Jenly + *

+ * Follow me */ public final class DecodeFormatManager { /** - * 所有的 + * 所有的支持的条码 */ public static final Map ALL_HINTS = new EnumMap<>(DecodeHintType.class); /** @@ -62,9 +64,9 @@ public final class DecodeFormatManager { } /** - * 所有支持的{@link BarcodeFormat} + * 所有支持的条码格式,具体格式可查看:{@link BarcodeFormat} * - * @return + * @return 所有支持的条码格式 */ private static List getAllFormats() { List list = new ArrayList<>(); @@ -90,6 +92,7 @@ public final class DecodeFormatManager { /** * 一维码 + *

* 包括如下几种格式: * {@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 getOneDimensionalFormats() { List list = new ArrayList<>(); @@ -124,7 +127,8 @@ public final class DecodeFormatManager { } /** - * 二维码 + * 二维码,具体格式可查看:{@link BarcodeFormat} + *

* 包括如下几种格式: * {@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 getTwoDimensionalFormats() { List list = new ArrayList<>(); @@ -146,13 +150,14 @@ public final class DecodeFormatManager { /** * 默认支持的格式 + *

* 包括如下几种格式: * {@link BarcodeFormat#QR_CODE} * {@link BarcodeFormat#UPC_A} * {@link BarcodeFormat#EAN_13} * {@link BarcodeFormat#CODE_128} * - * @return + * @return 默认支持的格式 */ private static List getDefaultFormats() { List list = new ArrayList<>(); @@ -167,7 +172,7 @@ public final class DecodeFormatManager { * 支持解码的格式 * * @param barcodeFormats {@link BarcodeFormat} - * @return + * @return 返回添加了通用配置后的解码支持类型与配置 */ public static Map createDecodeHints(@NonNull BarcodeFormat... barcodeFormats) { Map hints = new EnumMap<>(DecodeHintType.class); @@ -179,7 +184,7 @@ public final class DecodeFormatManager { * 支持解码的格式 * * @param barcodeFormat {@link BarcodeFormat} - * @return + * @return 返回添加了通用配置后的解码支持类型与配置 */ public static Map createDecodeHint(@NonNull BarcodeFormat barcodeFormat) { Map 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 hints, List formats) { // Image is known to be of one of a few possible formats. diff --git a/zxing-lite/src/main/java/com/king/zxing/analyze/AreaRectAnalyzer.java b/zxing-lite/src/main/java/com/king/zxing/analyze/AreaRectAnalyzer.java index babc205..428e3fd 100644 --- a/zxing-lite/src/main/java/com/king/zxing/analyze/AreaRectAnalyzer.java +++ b/zxing-lite/src/main/java/com/king/zxing/analyze/AreaRectAnalyzer.java @@ -15,6 +15,8 @@ import androidx.annotation.Nullable; * 矩阵区域分析器:主要用于锁定具体的识别区域 * * @author Jenly + *

+ * Follow me */ public abstract class AreaRectAnalyzer extends ImageAnalyzer { diff --git a/zxing-lite/src/main/java/com/king/zxing/analyze/BarcodeFormatAnalyzer.java b/zxing-lite/src/main/java/com/king/zxing/analyze/BarcodeFormatAnalyzer.java index 512fab5..805a77b 100644 --- a/zxing-lite/src/main/java/com/king/zxing/analyze/BarcodeFormatAnalyzer.java +++ b/zxing-lite/src/main/java/com/king/zxing/analyze/BarcodeFormatAnalyzer.java @@ -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 Jenly + *

+ * Follow me */ @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; diff --git a/zxing-lite/src/main/java/com/king/zxing/analyze/ImageAnalyzer.java b/zxing-lite/src/main/java/com/king/zxing/analyze/ImageAnalyzer.java index 6d2294d..94a2be1 100644 --- a/zxing-lite/src/main/java/com/king/zxing/analyze/ImageAnalyzer.java +++ b/zxing-lite/src/main/java/com/king/zxing/analyze/ImageAnalyzer.java @@ -20,6 +20,8 @@ import androidx.camera.core.ImageProxy; * 图像分析器 * * @author Jenly + *

+ * Follow me */ public abstract class ImageAnalyzer implements Analyzer { @@ -46,10 +48,11 @@ public abstract class ImageAnalyzer implements Analyzer { 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(); diff --git a/zxing-lite/src/main/java/com/king/zxing/analyze/MultiFormatAnalyzer.java b/zxing-lite/src/main/java/com/king/zxing/analyze/MultiFormatAnalyzer.java index 9a010ac..5c02ee9 100644 --- a/zxing-lite/src/main/java/com/king/zxing/analyze/MultiFormatAnalyzer.java +++ b/zxing-lite/src/main/java/com/king/zxing/analyze/MultiFormatAnalyzer.java @@ -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 Jenly + *

+ * Follow me */ @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; diff --git a/zxing-lite/src/main/java/com/king/zxing/analyze/QRCodeAnalyzer.java b/zxing-lite/src/main/java/com/king/zxing/analyze/QRCodeAnalyzer.java index 3b2e4ae..53c866c 100644 --- a/zxing-lite/src/main/java/com/king/zxing/analyze/QRCodeAnalyzer.java +++ b/zxing-lite/src/main/java/com/king/zxing/analyze/QRCodeAnalyzer.java @@ -14,6 +14,8 @@ import androidx.annotation.Nullable; * 二维码分析器 * * @author Jenly + *

+ * Follow me */ @SuppressWarnings("unused") public class QRCodeAnalyzer extends BarcodeFormatAnalyzer { diff --git a/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java b/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java index e881526..4b33faa 100644 --- a/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java +++ b/zxing-lite/src/main/java/com/king/zxing/util/CodeUtils.java @@ -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 Jenly + * @author Jenly + *

+ * Follow me */ @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 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 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 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 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 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 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 hints) { + @Nullable + public static String parseCode(@NonNull String bitmapPath, @Nullable Map 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 hints) { + @Nullable + public static String parseCode(@NonNull Bitmap bitmap, @Nullable Map 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 hints) { + @Nullable + public static Result parseCodeResult(@NonNull String bitmapPath, @Nullable Map 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 hints) { + @Nullable + public static Result parseCodeResult(@NonNull String bitmapPath, int reqWidth, int reqHeight, @Nullable Map 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 hints) { + @Nullable + public static Result parseCodeResult(@NonNull Bitmap bitmap, @Nullable Map hints) { return parseCodeResult(getRGBLuminanceSource(bitmap), hints); } @@ -400,7 +413,8 @@ public final class CodeUtils { * @param hints * @return */ - public static Result parseCodeResult(LuminanceSource source, Map hints) { + @Nullable + public static Result parseCodeResult(LuminanceSource source, @Nullable Map 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 hints) { + public static Bitmap createBarCode(@NonNull String content, @NonNull BarcodeFormat format, int desiredWidth, int desiredHeight, @Nullable Map 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 hints, boolean isShowText) { + public static Bitmap createBarCode(@NonNull String content, @NonNull BarcodeFormat format, int desiredWidth, int desiredHeight, @Nullable Map 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 hints, boolean isShowText, @ColorInt int codeColor) { + public static Bitmap createBarCode(@NonNull String content, @NonNull BarcodeFormat format, int desiredWidth, int desiredHeight, @Nullable Map 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 hints, boolean isShowText, int textSize, @ColorInt int codeColor) { + public static Bitmap createBarCode(@NonNull String content, @NonNull BarcodeFormat format, int desiredWidth, int desiredHeight, @Nullable Map 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;