二维码生成及扫码回调

本文介绍了如何使用Java编写的ZXingUtil工具类生成二维码,包括加密文本、添加logo以及解码二维码内容。同时展示了如何通过回调接口实现二维码扫描后触发特定操作。
摘要由CSDN通过智能技术生成

一、基础二维码生成

1.1 编写pom

<!-- 生成二维码依赖BEGIN -->
<dependency>
     <groupId>com.google.zxing</groupId>
     <artifactId>core</artifactId>
     <version>3.1.0</version>
 </dependency>
 <dependency>
     <groupId>com.google.zxing</groupId>
     <artifactId>javase</artifactId>
     <version>3.1.0</version>
 </dependency>
 <!-- 生成二维码依赖END -->

1.2 编写工具类

/**
 * 二维码的工具类
 */
@Slf4j
public class ZXingUtil {

    private static final int BLACK = 0xFF000000; //定义int类型的常量用于存放生成二维码时的类型
    private static final int WHITE = 0xFFFFFFFF;

    /**
     * 加密:文字-->图片  将文本变成二维数组,
     *
     * @param imagePath 图片路径
     * @param format    文件格式及后缀名
     * @param content   文本
     */
    public static void encodeImage(String imagePath, String format, String content, int width, int height, String logo) throws WriterException, IOException {

        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        //容错率:L(7%)<M(15%)<Q(25%)<H(35%);H容错率最高
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //编码格式
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        //外边距
        hints.put(EncodeHintType.MARGIN, 1);

        /*BarcodeFormat.QR_CODE:解析什么类型的文件:要解析的二维码的类型
        content:解析文件的内容
        width:生成二维码的宽
        height:生成二维码的高
        hints:涉及到加密用到的参数: 即 编码 和容错率*/
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        // 使BufferedImage勾画QRCode  (matrixWidth 是行二维码像素点)
        int matrixWidth = bitMatrix.getWidth();

        /*内存中的一张图片:是RenderedImage的子类,而RenderedImage是一个接口
        此时需要的图片是一个二维码-->需要一个boolean[][]数组存放二维码 --->Boolean数组是由BitMatrix产生的
        BufferedImage.TYPE_INT_RGB : 表示生成图片的类型: 此处是RGB模式*/
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //生成二维数组
        for (int x = 0; x < matrixWidth; x++) {
            for (int y = 0; y < matrixWidth; y++) {
                //二维坐标整个区域:画什么颜色
                img.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
            }
        }

        //将二维码图片转换成文件
        File file = new File(imagePath);
        //生成图片
        ImageIO.write(logoImg(img, logo), format, file);

    }

    /**
     * 解密,将生成的二维码转换成文字
     *
     * @param file:二维码文件
     */
    public static String decodeImage(File file) {

        //首先判断文件是否存在
        if (!file.exists()) {
            return "";
        }
        //将file转换成内存中的一张图片
        BufferedImage image = null;
        try {
            image = ImageIO.read(file);
        } catch (IOException e) {
            log.error("read ZXingCode failed", e);
        }
        MultiFormatReader formatter = new MultiFormatReader();
        assert image != null;
        LuminanceSource source = new BufferedImageLuminanceSource(image);
        Binarizer binarizer = new HybridBinarizer(source);
        BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
        //将图片的文字信息解析到result中
        Result result = null;
        try {
            result = formatter.decode(binaryBitmap);
        } catch (NotFoundException e) {
            log.error("parse data from ZXingCode failed", e);
        }
        assert result != null;
        log.info("parse data [{}] from ZXingCode", result.getText());
        return result.getText();
    }

    /**
     * 传logo和二维码,生成-->带logo的二维码
     *
     * @param matrixImage :二维码
     * @param logo        : 中间的logo
     * @return BufferedImage
     */
    public static BufferedImage logoImg(BufferedImage matrixImage, String logo) {
        // 在二维码上画logo:产生一个二维码画板
        Graphics2D g2 = matrixImage.createGraphics();
        // 画logo,将String类型的logo图片存放入内存中;即 string-->BufferedImage
        BufferedImage logoImage = null;
        try {
            logoImage = ImageIO.read(new File(logo));
        } catch (IOException e) {
            log.error("ZXingCode config logo read failed", e);
        }
        // 获取二维码的高和宽
        int height = matrixImage.getHeight();
        int width = matrixImage.getWidth();

        /*纯log图片
        logoImage:内存中的图片
        在二维码的高和宽的2/5,2/5开始画log,logo占用整个二维码的高和宽的1/5,1/5*/
        g2.drawImage(logoImage, width * 2 / 5, height * 2 / 5, width / 5, height / 5, null);


        /*画白色的外边框
        产生一个画白色圆角正方形的画笔
        BasicStroke.CAP_ROUND:画笔的圆滑程度,此处设置为圆滑
        BasicStroke.JOIN_ROUND:在边与边的连接点的圆滑程度,此处设置为圆滑*/
        BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        // 将画板和画笔关联起来
        g2.setStroke(stroke);

        // 画一个正方形, RoundRectangle2D是一个画长方形的类
        RoundRectangle2D.Float round = new RoundRectangle2D.Float(width * 2.0f / 5, height * 2.0f / 5, width * 1.0f / 5, height * 1.0f / 5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        //设置为画白色
        g2.setColor(Color.WHITE);
        g2.draw(round);

        //画灰色的内边框,原理与画白色边框相同
        BasicStroke stroke2 = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2.setStroke(stroke2);

        RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(width * 2.0f / 5 + 2, height * 2.0f / 5 + 2, width * 1.0f / 5 - 4, height * 1.0f / 5 - 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        //另一种设置灰色的方法:Color color = new Color(128,128,128);其中三个参数是 R G  B
        g2.setColor(Color.GRAY);
        g2.draw(round2);

        //释放内存
        g2.dispose();
        //刷新二维码
        matrixImage.flush();
        return matrixImage;
    }
}

1.3 编写测试代码并测试

@SpringBootTest(classes = {AppMain.class})
public class ZXingUtilTest {

    @Test
    public void testDownloadImg() throws Exception {
        String imagePath = "src/main/resources/zxingcode.jpeg";
        String logo = "src/main/resources/avatar-mine.jpeg";
        String content = "zhinian 👉🏻 只年";
        ZXingUtil.encodeImage(imagePath, "JPEG", content, 430, 430, logo);

        // 解密 -->将二维码内部的文字显示出来
        String s = ZXingUtil.decodeImage(new File(imagePath));
        System.out.printf(s);
    }
}

测试

头像和生成二维码图片如下

支付宝扫码如下

二、回调接口

2.1 编写回调接口

@Slf4j
@RestController
public class CallBackController {

    @RequestMapping("/call/doXxx")
    public void doXxx() {
        log.info("do callback success, are you ok?");
    }
}

2.2 生成二维码

注: 此步可编写为接口生成,二维码保存文件服务器,保存返回的文件地址

@SpringBootTest(classes = {AppMain.class})
public class ZXingUtilTest {

    @Test
    public void testDownloadImg() throws Exception {
        String imagePath = "src/main/resources/zxingcode.jpeg";
        String logo = "src/main/resources/avatar-mine.jpeg";
        // 同一wifi下, 电脑ip
        String content = "http://192.168.1.3:8888/call/doXxx";
        ZXingUtil.encodeImage(imagePath, "JPEG", content, 430, 430, logo);

        // 解密 -->将二维码内部的文字显示出来
        String s = ZXingUtil.decodeImage(new File(imagePath));
        System.out.printf(s);
    }
}

支付宝扫码

控制台输出
回调成功
回调成功,oh yeah !

  • 22
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

只年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值