[08]——快速集成ZXing生成二维码

首先需要依赖ZXing的核心库compile 'com.google.zxing:core:3.2.1'

查看最新的ZXing release版本

新建生成二维码的工具类:

public class QRCodeUtil {

    /**
     * 生成二维码Bitmap
     *
     * @param content   内容
     * @param widthPix  图片宽度
     * @param heightPix 图片高度
     * @param logoBm    二维码中心的Logo图标(可以为null)
     * @param filePath  用于存储二维码图片的文件路径
     * @return 生成二维码及保存文件是否成功
     */
    public static boolean createQRImage(String content, int widthPix, int heightPix, Bitmap logoBm, String filePath) {
        try {
            if (content == null || "".equals(content) || content.length() < 1) {
                return false;
            }

            //配置参数
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            //容错级别
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
            //设置空白边距的宽度
            hints.put(EncodeHintType.MARGIN, 0); //default is 4

            // 图像数据转换,使用了矩阵转换
            BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix, heightPix, hints);
            int[] pixels = new int[widthPix * heightPix];
            // 下面这里按照二维码的算法,逐个生成二维码的图片,
            // 两个for循环是图片横列扫描的结果
            for (int y = 0; y < heightPix; y++) {
                for (int x = 0; x < widthPix; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * widthPix + x] = 0xff000000;
                    } else {
                        pixels[y * widthPix + x] = 0xffffffff;
                    }
                }
            }

            // 生成二维码图片的格式,使用ARGB_8888
            Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);

            if (logoBm != null) {
                bitmap = addLogo(bitmap, logoBm);
            }

            //必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大!
            return bitmap != null && bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(filePath));
        } catch (WriterException | IOException e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * 在二维码中间添加Logo图案
     */
    private static Bitmap addLogo(Bitmap src, Bitmap logo) {
        if (src == null) {
            return null;
        }

        if (logo == null) {
            return src;
        }

        //获取图片的宽高
        int srcWidth = src.getWidth();
        int srcHeight = src.getHeight();
        int logoWidth = logo.getWidth();
        int logoHeight = logo.getHeight();

        if (srcWidth == 0 || srcHeight == 0) {
            return null;
        }

        if (logoWidth == 0 || logoHeight == 0) {
            return src;
        }

        //logo大小为二维码整体大小的1/5
        float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;
        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.ALL_SAVE_FLAG);
            canvas.restore();
        } catch (Exception e) {
            bitmap = null;
            e.getStackTrace();
        }

        return bitmap;
    }
}

在Activity中使用:

@OnClick(R.id.btn_create_qrcode)
public void onClick() {
    final File outputPic = makeTempFile(mContext, Environment.getExternalStorageDirectory().getPath() + "/uerb/test/", "qr_", ".jpg");
    //二维码图片较大时,生成图片、保存文件的时间可能较长,因此放在新线程中
    new Thread(new Runnable() {
        @Override
        public void run() {
            boolean success = QRCodeUtil.createQRImage(mEtQrcodeContent.getText().toString().trim(), mIvQrcodeImage.getWidth(), mIvQrcodeImage.getWidth(), null, outputPic.getAbsolutePath());

            if (success) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mIvQrcodeImage.setImageBitmap(BitmapFactory.decodeFile(outputPic.getAbsolutePath()));
                    }
                });
            }
        }
    }).start();
}


@SuppressWarnings({"ConstantConditions", "ResultOfMethodCallIgnored"})
public static File makeTempFile(@NonNull Context context, @Nullable String saveDir, String prefix, String extension) {
    if (saveDir == null)
        saveDir = context.getExternalCacheDir().getAbsolutePath();
    final String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
    final File dir = new File(saveDir);
    dir.mkdirs();
    return new File(dir, prefix + timeStamp + extension);
}

常用的生成二维码的一些配置:

Map<EncodeHintType, Object> hints = new HashMap<>();
//指定字符集
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
//容错级别,容错级别越高生成的二维码越复杂
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
//设置空白边距的宽度
hints.put(EncodeHintType.MARGIN, 0); //default is 4
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容