使用Java打造自己的个性二维码

1,342 阅读3分钟

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

| 作者:江夏

| CSDN:blog.csdn.net/qq_41153943

| 掘金:juejin.cn/user/651387…

| 知乎:www.zhihu.com/people/1024…

| GitHub:github.com/JiangXia-10…

本文大概1165字,建议阅读9分钟

前言

二维码在生活中是很常见的东西了,它的出现大大方便了我们的日常生活。买东西付款只需要扫一下二维码就行了, 访问网址也可以直接访问二维码,现在疫情登记信息也可以使用二维码。之前的一篇文章:Python制作属于自己的第一个二维码介绍了如何使用python生成二维码,并且介绍了二维码相关的概念和原理,具体的可以参考之前的文章。

python是兴趣,公司的日常开发大多使用的是java,最近刚好有个二维码相关的需求。所以这篇文章就总结下如何使用java来生成二维码。

实战

java生成二维码主要有三种方式:

1、使用SwetakeQRCode

2、使用BarCode4j

3、使用google的zxing

我这里是在springboot项目种使用的第三种google的zxing。所以首先需要添加zxing的相关依赖:

<!--二维码相关的依赖-->
<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>

接着定义一个工具类,声明二维码编码格式、尺寸等数据:

//编码格式
private static final String CHARSET = "utf-8";
//生成的文件类型,这里为jpg格式
private static final String FORMAT_NAME = "jpg";
// 二维码尺寸
private static final int QRCODE_SIZE = 300;
//宽度
private static final int WIDTH = 60;
//高度
private static final int HEIGHT = 60;

这里可以使用自己喜欢的图片进行自定义的二维码,所以定义一个插入个人喜好图片的方法:

 private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {
        File file = new File(imgPath);
        //首先需要判断图片是否存在
        if (!file.exists()) {
            System.err.println("" + imgPath + "   该文件不存在!");
            return;
        }
        //读取图片
        Image src = ImageIO.read(new File(imgPath));
        //获取图片的宽度和高度
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        // 当图片大小过大时对其进行压缩
        if (needCompress) {
            if (width > WIDTH) {
                width = WIDTH;
            }
            if (height > HEIGHT) {
                height = HEIGHT;
            }
            Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();
            //绘制缩小后的图
            g.drawImage(image, 0, 0, null);
            g.dispose();
            src = image;
        }
        //插入图片
        Graphics2D graph = source.createGraphics();
        int x = (QRCODE_SIZE - width) / 2;
        int y = (QRCODE_SIZE - height) / 2;
        graph.drawImage(src, x, y, width, height, null);
        Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }

生成二维码图片的具体方法:

/**
     * 生成图片
     * @param content 具体内容 比如这里是网址
     * @param imgPath 图片的路径
     * @param needCompress 是否需要压缩图片,当图片的尺寸大于二维码尺寸时对其进行压缩
     * @return
     * @throws Exception
     */
    private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
                hints);
        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 : 0xFFFFFFFF);
            }
        }
        if (imgPath == null || "".equals(imgPath)) {
            return image;
        }
        // 调用插入图片的方法插入自定义图片
        QRCode.insertImage(image, imgPath, needCompress);
        return image;
    }

调用上面的方法生成二维码:

//真正的生成二维码的方法
public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
    BufferedImage image = QRCode.createImage(content, imgPath, needCompress);
    String file = System.currentTimeMillis()+".jpg";
    ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
}

编写一个测试方法测试上述代码是否正确:

//自定义的网站
String text = "http://www.baidu.com";
//二维码包含的图片
String logoPath = "C:\\Users\\Administrator\\Desktop\\1de5159fb88f492a666a1976f5495f43.jpg";
//二维码保存的地址
String destPath = "C:\\Users\\Administrator\\Desktop\\test";
//生成二维码
QRCode.encode(text, logoPath, destPath, true);

运行后在桌面的test文件夹下生成了百度网址对应的二维码如下:

这里使用的个性图片如下,可以发现该图片确实被压缩在了二维码的正中间:

然后我们用手机的相机扫描上面二维码就可以直接访问到百度的首页了。

上述的代码是将网址或者数据信息进行加密从而生成二维码,同理也可以对二维码图片进行解析从而输出其具体的内容,解析方法如下:

/**
     * 对二维码进行解析的具体方法
     * @param file
     * @return
     * @throws Exception
     */
    public static String decode(File file) throws Exception {
        BufferedImage image;
        image = ImageIO.read(file);
        if (image == null) {
            return null;
        }
        BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
        Result result;
        Hashtable hints = new Hashtable();
        hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
        result = new MultiFormatReader().decode(bitmap, hints);
        String resultStr = result.getText();
        return resultStr;
    }

编写一个测试类对刚刚生成的二维码进行解析并输出解析结果:

// 调用解析二维码
String str = QRCode.decode("C:\\Users\\Administrator\\Desktop\\test\\1628420962518.jpg");
// 打印出解析出的内容
System.out.println(str);

结尾

上面就是java中生成个性二维码的内容,代码会同步至github,具体下载地址:github.com/JiangXia-10…

有任何问题或者不正确的地方欢迎讨论指正!

相关推荐: