如何生成二维码?



一、关于扫一扫二维码登录?关于支付端的二维码?关于扫二维码添加好友?

理解:无论是何种功能的二维码,它都是基于生成该二维码的请求,列如:扫码登录对应一个扫码后登录的Api、扫码支付对应支付的Api、扫码加好友对应加好友的Api。

//引入谷歌提供的二维码依赖
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.3.0</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.3.0</version>
</dependency>
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
</dependency>

源码解析


二、关于生成几种常见样式的二维码?

市面上生成二维码的技术:

1、google:zxing(主流的,但只能生成黑白相间(普通和logo)的二维码)

2、github:qrcode(基于zxing,可生成绚丽多彩的二维码,如下:)


三、实现:QrCodeController、ZxingUtil、QrCodeUtil、index.html
   //构建生成二维码项目所需依赖
	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.0</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
<!--        google:zxing-->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.3.0</version>
        </dependency>
<!--        github:qrCode-->
        <dependency>
            <groupId>com.github.liuyueyi.media</groupId>
            <artifactId>qrcode-plugin</artifactId>
            <version>2.5.2</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>
//静态资源下的:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script language="JavaScript" src="jquery-3.5.1.js"></script>
    <title>单文件上传</title>
</head>
<style>
    img[src=""].img:not([src]){
        opacity: 0;
    }
</style>
<body>
    <a href="javascript:void(0)" onclick="uploadPhoto()">选择图片</a>
    <input type="file" id="photoFile">
    <input type="text" id="text" placeholder="请输入跳转链接">
    <img id="preview_photo" src="" width="200px" height="200px">
    <ul>
        <li><input type="button" id="normal" value="生成普通二维码" onclick="upload('normal')"></li>
        <li><input type="button" id="logo" value="生成logo二维码" onclick="upload('logo')"></li>
        <li><input type="button" id="color" value="生成彩色二维码" onclick="upload('color')"></li>
        <li><input type="button" id="background" value="生成带背景二维码" onclick="upload('background')"></li>
        <li><input type="button" id="style" value="生成特殊形状二维码" onclick="upload('style')"></li>
        <li><input type="button" id="imageFile" value="生成图片二维码" onclick="upload('imageFile')"></li>
        <li><input type="button" id="gif" value="生成gif二维码" onclick="upload('gif')"></li>
    </ul>
</body>
<script>
    function uploadPhoto() {
        $('#photoFile').click();
    }

    /**
     * 上传图片
     * @param flag
     */
    function upload(flag) {
        let formData = new FormData();
        formData.append('logoFile',document.getElementById('photoFile').files[0]);
        formData.append('text',document.getElementById('text').value);
        formData.append('flag',flag);
        $.ajax({
            url:"http://localhost:8080/create",
            type:"post",
            data:formData,
            contentType:false,
            processData: false,
            success:function (data) {
                $('#preview_photo').attr("src","data:image/jpeg;base64,"+data)
            },
            error:function (data) {
                alert("上传失败")
            }
        })
    }
</script>
</html>
//用于返回 生成二维码的base64字符串格式图片
/**
 * 基于Zxing jar包生成普通和logo二维码
 * @Author:LuJiaHong
 * @Date:2021/1/27~3:55:57
 * @Version 1.0
 */
public class ZxingUtil {

    public static String createImage(String text, InputStream imgPath) throws Exception{
        HashMap map = new HashMap();
        map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//纠错程度
        map.put(EncodeHintType.CHARACTER_SET,"utf-8");//字符编码
        map.put(EncodeHintType.MARGIN,1);//边距

        BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE,300,300,map);

        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

        for(int x = 0 ; x < width ; x++){
            for(int y = 0; y < height ; y++){
                image.setRGB(x,y,bitMatrix.get(x,y) ? 0xFF000000 : 0xFFFFFF);
            }
        }
        if(imgPath == null){
            return imageToBase64(image);
        }
        image = insertLogo(image,imgPath);
        return imageToBase64(image);
    }

    /**
     * 生成logo二维码
     * @param image
     * @param imgPath
     * @return
     * @throws Exception
     */
    private static BufferedImage insertLogo(BufferedImage image, InputStream imgPath) throws Exception{
        Image logo = ImageIO.read(imgPath);
        int w = logo.getWidth(null);
        int h = logo.getHeight(null);
        if(w>100){
            w=100;
        }
        if(h>100){
            h=100;
        }
        Image logo1 = logo.getScaledInstance(w,h,Image.SCALE_SMOOTH);
        BufferedImage bfImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
        Graphics g = bfImage.getGraphics();
        g.drawImage(logo1,0,0,null);
        g.dispose();

        Graphics2D gra = image.createGraphics();
        int x = (300-w)/2;
        int y = (300-h)/2;
        gra.drawImage(logo1,x,y,null);
        Shape shape = new RoundRectangle2D.Double(x,y,w,h,6,6);//设置圆角
        gra.setStroke(new BasicStroke(3f));//设置画笔粗细
        gra.draw(shape);
        gra.dispose();//释放资源
        return image;
    }

    /**
     * 图片转为base64格式
     * @param image
     * @return
     * @throws Exception
     */
    public static String imageToBase64(BufferedImage image) throws Exception{
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(image,"png",os);
        return Base64.encodeBase64String(os.toByteArray());
    }
/**
 * 基于gitHub上开源的QrCode jar包生成各种类型二维码
 * @Author:LuJiaHong
 * @Date:2021/1/31~23:32:22
 * @Version 1.0
 */
public class QrCodeUtil {
    /**
     * 普通二维码
     * @param text
     * @return
     * @throws Exception
     */
    public static String normal(String text) throws Exception {
        return QrCodeGenWrapper.of(text).asString();
    }

    /**
     * logo二维码
     * @param text
     * @param logoFile
     * @return
     * @throws Exception
     */
    public static String logo(String text, InputStream logoFile) throws Exception {
        return QrCodeGenWrapper
                .of(text)
                .setLogo(logoFile)
                .setLogoRate(7)
                .setLogoStyle(QrCodeOptions.LogoStyle.ROUND)
                .asString();
    }

    /**
     * 带颜色二维码
     * @param text
     * @return
     * @throws Exception
     */
    public static String color(String text) throws Exception {
        return QrCodeGenWrapper
                .of(text)
                .setDrawBgColor(Color.red)
                .asString();
    }

    /**
     * 带背景图标二维码
     * @param text
     * @param bgFile
     * @return
     * @throws Exception
     */
    public static String backGround(String text, InputStream bgFile) throws Exception {
        return QrCodeGenWrapper
                .of(text)
                .setBgImg(bgFile)
// .setBgStyle(QrCodeOptions.BgImgStyle.FILL)//填充模式
.setBgStyle(QrCodeOptions.BgImgStyle.PENETRATE)//渲染模式
                .setBgH(500)
                .setBgW(500)
                .setW(500)
                .setH(500)
//                .setBgStartX(130)
//                .setBgStartY(130)
//                .setBgOpacity(0.5f)
                .asString();
    }

    /**
     * 特殊形状二维码
     * @param text
     * @return
     * @throws Exception
     */
    public static String style(String text) throws Exception {
        return QrCodeGenWrapper
                .of(text)
                .setBgH(500)
                .setBgW(500)
                .setW(500)
                .setH(500)
                .setDrawEnableScale(true)
               .setDrawStyle(QrCodeOptions.DrawStyle.CIRCLE)
                .asString();
    }

    /**
     * 生成图片二维码
     * @param text
     * @param bgFile
     * @return
     * @throws Exception
     */
    public static String imageFile(String text, InputStream bgFile) throws Exception {
        return QrCodeGenWrapper
                .of(text)
                .setW(500)
                .setH(500)
                .setDrawEnableScale(true)
                .setErrorCorrection(ErrorCorrectionLevel.H)
                .setDrawStyle(QrCodeOptions.DrawStyle.IMAGE)
                .addImg(1,1,bgFile)
                .asString();
    }

    /**
     * 生成gif二维码
     * @param text
     * @param bgFile
     * @return
     * @throws Exception
     */
    public static String gif(String text, InputStream bgFile) throws Exception {
        return QrCodeGenWrapper
                .of(text)
                .setW(500)
                .setH(500)
                .setBgImg(bgFile)
                .setBgOpacity(0.5f)
                .setPicType("gif")
                .asString();
    }
}
//供异步请求获取 生成的Base64二维码图片 控制层
@RestController
public class QrCodeController {
    @RequestMapping("/create")
    public String CreateQrCode(@RequestParam(value = "logoFile",required = false)MultipartFile file,
                               @RequestParam(value = "text")String text,
                               @RequestParam(value = "flag")String flag){
        try {
            if(file != null){
                if("logo".equals(flag)) {
//return ZxingUtil.createImage(text,file.getInputStream());
                    return QrCodeUtil.logo(text,file.getInputStream());
                }else if ("background".equals(flag)){
                    return QrCodeUtil.backGround(text,file.getInputStream());
                }else if ("imageFile".equals(flag)){
                    return QrCodeUtil.imageFile(text,file.getInputStream());
                }else if ("gif".equals(flag)){
                    return QrCodeUtil.gif(text,file.getInputStream());
                }
            }else{
                if("normal".equals(flag)) {
//                return ZxingUtil.createImage(text,null);
                    return QrCodeUtil.normal(text);
                }else if ("color".equals(flag)){
                    return QrCodeUtil.color(text);
                }else if ("style".equals(flag)){
                    return QrCodeUtil.style(text);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "hello";
    }
}

四、说明

按给定的跳转链接(字段)和背景图片,生成的指定样式二维码,微信扫码即可实现链接的跳转(获取字段)

视频教学


文章作者: LJH
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LJH !
 上一篇
2021-12-14 LJH
下一篇 
2021-12-14 LJH
  目录