美文网首页
Android ZXing 二维码工具类

Android ZXing 二维码工具类

作者: afkT | 来源:发表于2020-01-26 22:28 被阅读0次

    DevUtils Github

    方法 注释
    createQRCodeImage 生成二维码图片
    decodeQRCode 解析二维码图片
    getResultData 获取扫描结果数据
    syncEncodeQRCode 同步创建黑色前景色、白色背景色的二维码图片
    addLogoToQRCode 添加 Logo 到二维码图片上
    onResult 生成二维码结果回调
    package dev.other;
    
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.DecodeHintType;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.RGBLuminanceSource;
    import com.google.zxing.Result;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    import java.util.EnumMap;
    import java.util.Map;
    
    import dev.utils.LogPrintUtils;
    import dev.utils.common.thread.DevThreadManager;
    
    /**
     * detail: ZXing 二维码工具类
     * @author Ttt
     */
    public final class ZXingQRCodeUtils {
    
        private ZXingQRCodeUtils() {
        }
    
        private static final String TAG = ZXingQRCodeUtils.class.getSimpleName();
    
        // ==============
        // = 生成二维码 =
        // ==============
    
        /**
         * detail: 生成二维码结果回调
         * @author Ttt
         */
        public interface QRResultCallBack {
    
            /**
             * 生成二维码结果回调
             * @param success 是否成功
             * @param bitmap  成功图片
             * @param e       异常信息
             */
            void onResult(boolean success, Bitmap bitmap, Exception e);
        }
    
        // =
    
        /**
         * 生成二维码图片
         * @param content 生成内容
         * @param size    图片宽高大小 ( 正方形 px )
         */
        public static void createQRCodeImage(final String content, final int size) {
            createQRCodeImage(content, size, null, null);
        }
    
        /**
         * 生成二维码图片
         * @param content          生成内容
         * @param size             图片宽高大小 ( 正方形 px )
         * @param qrResultCallBack 生成结果回调
         */
        public static void createQRCodeImage(final String content, final int size, final QRResultCallBack qrResultCallBack) {
            createQRCodeImage(content, size, null, qrResultCallBack);
        }
    
        /**
         * 生成二维码图片
         * @param content          生成内容
         * @param size             图片宽高大小 ( 正方形 px )
         * @param logo             中间 Logo
         * @param qrResultCallBack 生成结果回调
         */
        public static void createQRCodeImage(final String content, final int size, final Bitmap logo, final QRResultCallBack qrResultCallBack) {
            DevThreadManager.getInstance(10).execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 生成二维码图片
                        Bitmap qrCodeBitmap = syncEncodeQRCode(content, size);
                        if (logo != null) { // 中间 Logo
                            qrCodeBitmap = addLogoToQRCode(qrCodeBitmap, logo);
                        }
                        // 触发回调
                        if (qrResultCallBack != null) {
                            qrResultCallBack.onResult(true, qrCodeBitmap, null);
                        }
                    } catch (Exception e) {
                        LogPrintUtils.eTag(TAG, e, "createQRCodeImage");
                        // 触发回调
                        if (qrResultCallBack != null) {
                            qrResultCallBack.onResult(false, null, e);
                        }
                    }
                }
            });
        }
    
        // ==============
        // = 解析二维码 =
        // ==============
    
        // 解析配置
        private static final Map<DecodeHintType, Object> DECODE_HINTS = new EnumMap<>(DecodeHintType.class);
    
        /**
         * detail: 二维码扫描结果回调
         * @author Ttt
         */
        public interface QRScanCallBack {
    
            /**
             * 二维码扫描结果回调
             * @param success 是否成功
             * @param result  识别数据 {@link Result}
             * @param e       异常信息
             */
            void onResult(boolean success, Result result, Exception e);
        }
    
        // =
    
        /**
         * 解析二维码图片
         * @param bitmap         待解析的二维码图片
         * @param qrScanCallBack 解析结果回调
         */
        public static void decodeQRCode(final Bitmap bitmap, final QRScanCallBack qrScanCallBack) {
            if (bitmap == null) {
                if (qrScanCallBack != null) {
                    qrScanCallBack.onResult(false, null, new Exception("bitmap is null"));
                }
                return;
            }
            // 开始解析
            DevThreadManager.getInstance(5).execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        int width = bitmap.getWidth();
                        int height = bitmap.getHeight();
                        int[] pixels = new int[width * height];
                        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
                        RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
                        Result result = new MultiFormatReader().decode(new BinaryBitmap(new HybridBinarizer(source)), DECODE_HINTS);
                        // 触发回调
                        if (qrScanCallBack != null) {
                            qrScanCallBack.onResult((result != null), result, null);
                        }
                    } catch (Exception e) {
                        LogPrintUtils.eTag(TAG, e, "decodeQRCode");
                        // 触发回调
                        if (qrScanCallBack != null) {
                            qrScanCallBack.onResult(false, null, e);
                        }
                    }
                }
            });
        }
    
        // ============
        // = 获取结果 =
        // ============
    
        /**
         * 获取扫描结果数据
         * @param result 识别数据 {@link Result}
         * @return 扫描结果数据
         */
        public static String getResultData(final Result result) {
            return (result != null) ? result.getText() : null;
        }
    
        // ========
        // = 编码 =
        // ========
    
        // 编码类型
        private static final Map<EncodeHintType, Object> ENCODE_HINTS = new EnumMap<>(EncodeHintType.class);
    
        static {
            // 编码类型
            ENCODE_HINTS.put(EncodeHintType.CHARACTER_SET, "utf-8");
            // 指定纠错等级, 纠错级别 ( L 7%、M 15%、Q 25%、H 30% )
            ENCODE_HINTS.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            // 设置二维码边的空度, 非负数
            ENCODE_HINTS.put(EncodeHintType.MARGIN, 0);
        }
    
        /**
         * 同步创建黑色前景色、白色背景色的二维码图片
         * @param content 生成内容
         * @param size    图片宽高大小 ( 正方形 px )
         * @return 二维码图片
         */
        public static Bitmap syncEncodeQRCode(final String content, final int size) {
            return syncEncodeQRCode(content, size, Color.BLACK, Color.WHITE);
        }
    
        /**
         * 同步创建指定前景色、指定背景色二维码图片
         * <pre>
         *     该方法是耗时操作, 请在子线程中调用
         * </pre>
         * @param content         生成内容
         * @param size            图片宽高大小 ( 正方形 px )
         * @param foregroundColor 二维码图片的前景色
         * @param backgroundColor 二维码图片的背景色
         * @return 二维码图片
         */
        public static Bitmap syncEncodeQRCode(final String content, final int size, final int foregroundColor, final int backgroundColor) {
            try {
                BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, ENCODE_HINTS);
                int[] pixels = new int[size * size];
                for (int y = 0; y < size; y++) {
                    for (int x = 0; x < size; x++) {
                        if (matrix.get(x, y)) {
                            pixels[y * size + x] = foregroundColor;
                        } else {
                            pixels[y * size + x] = backgroundColor;
                        }
                    }
                }
                Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
                bitmap.setPixels(pixels, 0, size, 0, 0, size, size);
                return bitmap;
            } catch (Exception e) {
                LogPrintUtils.eTag(TAG, e, "syncEncodeQRCode");
                return null;
            }
        }
    
        /**
         * 添加 Logo 到二维码图片上
         * <pre>
         *     非最优方法, 该方式是直接把 Logo 覆盖在图片上会遮挡部分内容
         * </pre>
         * @param src  二维码图片
         * @param logo Logo
         * @return 含 Logo 二维码图片
         */
        public static Bitmap addLogoToQRCode(final Bitmap src, final Bitmap logo) {
            if (src == null || logo == null) return src;
            // 获取图片宽度高度
            int srcWidth = src.getWidth();
            int srcHeight = src.getHeight();
            int logoWidth = logo.getWidth();
            int logoHeight = logo.getHeight();
            // 缩放图片
            float scaleFactor = srcWidth * 1.0f / 4 / logoWidth; // 这里的 4 决定 Logo 在图片的比例 四分之一
            Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
            try {
                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.save();
                canvas.restore();
            } catch (Exception e) {
                LogPrintUtils.eTag(TAG, e, "addLogoToQRCode");
                bitmap = null;
            }
            return bitmap;
        }
    }
    

    相关文章

      网友评论

          本文标题:Android ZXing 二维码工具类

          本文链接:https://www.haomeiwen.com/subject/krrsthtx.html