qrcode-plugin生成二维码分析和使用

导入依赖

来源于一个开源项目中的一部分,qrcode-plugin在开源二维码处理库zxing的基础上,重新写了二维码渲染的逻辑。以支持更灵活、更个性化的二维码生成规则,封装了二维码的生成解析,深度指定了二维码的生成,支持各种酷炫二维码的产生。

    <dependency>
      <groupId>com.github.liuyueyi.media</groupId>
      <artifactId>qrcode-plugin</artifactId>
      <version>2.5.2</version>
    </dependency>

编写控制层

 BufferedImage image = QrCodeGenWrapper.of(url)
                    .asBufferedImage();//生成普通二维码

分析:

1.在zxing创建二维码时候要传入校验级别、编码集、四周留白参数然后利用多格式写入器.encode(内容,格式,宽度,高度,参数)生成二维数组(矩阵) BitMatrix

2.将矩阵交给BufferImage生成二维码

    //2.创建一个map用于存放 二维码参数
            Map map = new HashMap();
            //2.1存放二维码校正级别
            map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            //2.2存放编码集
            map.put(EncodeHintType.CHARACTER_SET,"utf-8");
            //2.3四周留白
            map.put(EncodeHintType.MARGIN,1);
            //3.创建多格式写入器
            MultiFormatWriter writer = new MultiFormatWriter();
            //生成一个矩阵数组
            BitMatrix encode = writer.encode(url, BarcodeFormat.QR_CODE, 400, 400, map);
            //3.1获取高度宽度
            int w = encode.getWidth();
            int h = encode.getHeight();
            //4.生成二维码
            //4.1创建BufferedImage
            BufferedImage image = new BufferedImage(w,h,BufferedImage.TYPE_INT_BGR);
            //遍历矩阵
            for (int i = 0; i < w; i++) {
                for (int j = 0; j < h; j++) {
                    image.setRGB(i,j,encode.get(i,j)?0x000000:0xFFFFFF);
                }
            }

而qrcode只用了一个of传入内容和asBufferedImage 就生成了二维码。根据这个分析

1.找到qrcode下的QrCodeGenWrapper类我猜测这是个主入口它调用了of,of是它里面的一个静态方法,返回一个Buider类型,而我们现在未知Builder是什么?带着疑问去找到Builder。

 public static Builder of(String content) {
        return new Builder().setMsg(content);
    }

2.我在QrCodeGenWrapper中找到了Builder,它是一个静态内部类,它里面设置了许多属性和get set 方法 ,我仔细观看 又msg w h  code padding...这不正是我在zxing生成二维码需要传入的参数码,我就猜测Buider应该是在生成二维码时候为encode传参用的相当于我在上面创建的一个map然后传入校正,编码集,宽高等参数

 map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            //2.2存放编码集
            map.put(EncodeHintType.CHARACTER_SET,"utf-8");
            //2.3四周留白
            map.put(EncodeHintType.MARGIN,1);

然后我根据前面调用的asBufferedImage方法我肯定是它生层了二维码,点进去观察

public BufferedImage asBufferedImage() throws IOException, WriterException {
            return QrCodeGenWrapper.asBufferedImage(build());
        }

它返回一个BufferedImage类型确实是生成二维码返回的参数,但它没有用到Builder进行传参,方法里调用的方法参数是一个build方法进行传参我猜测Buider可能在里面进行处理,点击去。

private QrCodeOptions build() {
            this.validate();

            QrCodeOptions qrCodeConfig = new QrCodeOptions();
            qrCodeConfig.setMsg(getMsg());
            qrCodeConfig.setH(getH());
            qrCodeConfig.setW(getW());


            // 设置背景信息
            QrCodeOptions.BgImgOptions bgOp = bgImgOptions.build();
            if (bgOp.getBgImg() == null && bgOp.getGifDecoder() == null) {
                qrCodeConfig.setBgImgOptions(null);
            } else {
                qrCodeConfig.setBgImgOptions(bgOp);
            }


            // 设置logo信息
            QrCodeOptions.LogoOptions logoOp = logoOptions.build();
            if (logoOp.getLogo() == null) {
                qrCodeConfig.setLogoOptions(null);
            } else {
                qrCodeConfig.setLogoOptions(logoOp);
            }


            // 绘制信息
            QrCodeOptions.DrawOptions drawOp = drawOptions.build();
            qrCodeConfig.setDrawOptions(drawOp);


            // 设置detect绘制信息
            QrCodeOptions.DetectOptions detectOp = detectOptions.build();
            if (detectOp.getOutColor() == null && detectOp.getInColor() == null) {
                detectOp.setInColor(drawOp.getPreColor());
                detectOp.setOutColor(drawOp.getPreColor());
            } else if (detectOp.getOutColor() == null) {
                detectOp.setOutColor(detectOp.getOutColor());
            } else if (detectOp.getInColor() == null) {
                detectOp.setInColor(detectOp.getInColor());
            }
            qrCodeConfig.setDetectOptions(detectOp);


            if (qrCodeConfig.getBgImgOptions() != null &&
                    qrCodeConfig.getBgImgOptions().getBgImgStyle() == QrCodeOptions.BgImgStyle.PENETRATE) {
                // 透传,用背景图颜色进行绘制时
                drawOp.setPreColor(ColorUtil.OPACITY);
                qrCodeConfig.getBgImgOptions().setOpacity(1);
                qrCodeConfig.getDetectOptions().setInColor(ColorUtil.OPACITY);
                qrCodeConfig.getDetectOptions().setOutColor(ColorUtil.OPACITY);
            }

            // 设置输出图片格式
            qrCodeConfig.setPicType(picType);

            // 设置精度参数
            Map<EncodeHintType, Object> hints = new HashMap<>(3);
            hints.put(EncodeHintType.ERROR_CORRECTION, errorCorrection);
            hints.put(EncodeHintType.CHARACTER_SET, code);
            hints.put(EncodeHintType.MARGIN, this.getPadding());
            qrCodeConfig.setHints(hints);

            return qrCodeConfig;
        }

buid方法返回一个QrCodeOptions 类型 分析方法里面内容确实Buider获取的内容给到了QrCodeOptions对象并进行返回。

3.然后再回到asBufferedImage分析 QrCodeGenWrapper.asBufferedImage(build());方法。点进去

private static BufferedImage asBufferedImage(QrCodeOptions qrCodeOptions) throws WriterException, IOException {
        try {
            BitMatrixEx bitMatrix = QrCodeGenerateHelper.encode(qrCodeOptions);
            return QrCodeGenerateHelper.toBufferedImage(qrCodeOptions, bitMatrix);
        } finally {
            QuickQrUtil.clear();
        }
    }

我发现他也返回BufferImage类型说明asBufferedImage返回的是它的值,看到这里有个矩阵和BufferImage顺序对上了,在zxing创建二维码也是这个顺序。我点进QrCodeGenerateHelper查看


/**
 * 二维码生成辅助类,主要两个方法,一个是生成二维码矩阵,一个是渲染矩阵为图片
 * Created by yihui on 2018/3/23.
 */
public class QrCodeGenerateHelper {
  

4.先来分析它的生成二维码矩阵方法

public static BitMatrixEx encode(QrCodeOptions qrCodeConfig) throws WriterException {
        ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;
        int quietZone = 1;
        if (qrCodeConfig.getHints() != null) {
            if (qrCodeConfig.getHints().containsKey(EncodeHintType.ERROR_CORRECTION)) {
                errorCorrectionLevel = ErrorCorrectionLevel
                        .valueOf(qrCodeConfig.getHints().get(EncodeHintType.ERROR_CORRECTION).toString());
            }
            if (qrCodeConfig.getHints().containsKey(EncodeHintType.MARGIN)) {
                quietZone = Integer.parseInt(qrCodeConfig.getHints().get(EncodeHintType.MARGIN).toString());
            }

            if (q
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值