2021-1-26-java生成二维码

使用java生成QRCode二维码

需要引入zxing依赖:
<!--   google zxing qrcode生成依赖  -->
<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>
生成二维码
/**
 * @author liuminkai
 * @version 1.0
 * @datetime 2021/1/27 15:02
 * @decription zxing生成
 **/
public class CreateQRCode {
    public static void main(String[] args) {
        // vCard2.1
        String content = "BEGIN:VCARD"+"\n"
                +"VERSION:2.1"+"\n"
                +"N:姓;名"+"\n"
                +"FN:姓名"+"\n"
                +"NICKNAME:nickName"+"\n"
                +"ORG:公司;部门"+"\n"
                +"TITLE:职位"+"\n"
                +"TEL;WORK;VOICE:电话1"+"\n"
                +"TEL;WORK;VOICE:电话2"+"\n"
                +"TEL;HOME;VOICE:电话1"+"\n"
                +"TEL;HOME;VOICE:电话2"+"\n"
                +"TEL;CELL;VOICE:13590342862"+"\n"
                +"TEL;PAGER;VOICE:0755"+"\n"
                +"TEL;WORK;FAX:传真"+"\n"
                +"TEL;HOME;FAX:传真"+"\n"
                +"ADR;WORK:;;单位地址;深圳;广东;433000;国家"+"\n"
                +"ADR;HOME;POSTAL; PARCEL:;;街道地址;深圳;广东;433330;中国"+"\n"
                +"URL:网址"+"\n"
                +"URL:单位主页"+"\n"
                +"EMAIL;PREF;INTERNET:邮箱地址"+"\n"
                +"X-QQ:11111111"+"\n"
                +"END:VCARD" ;
        createQRCode(content);
    }
    public static void createQRCode(String content){
        createQRCode(content, "QRCode.png");
    }
    public static void createQRCode(String content, String fileName){
        createQRCode(content, 500, 500, "png", fileName);
    }
    /**
     * 二维码生成
     * @date 2021/1/27 15:34
     * @param content 内容
     * @param width 宽
     * @param height 高
     * @param format 图片格式
     * @param fileName 生成图片的文件名
     * @return void
     **/
    public static void createQRCode(String content, int width, int height, String format, String fileName){
        // 二维码配置
        Map hints = new HashMap();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 二维码编码utf-8
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); // 纠错级别(L < M < Q < H) 级别越高,存储数据越少
        hints.put(EncodeHintType.MARGIN, 1); // 外边框大小
        // 生成二维码
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            Path file = new File(fileName).toPath();
            MatrixToImageWriter.writeToPath(bitMatrix, format, file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行程序,会在项目根目录下生成 QRCode.png图片

解析二维码
/**
 * @author liuminkai
 * @version 1.0
 * @datetime 2021/1/27 15:46
 * @decription 解析二维码
 **/
public class ReadQRCode {
    public static void main(String[] args) throws IOException, NotFoundException {
        System.out.println("解析的结果: \n " + readQRcode());
    }

    /**
     * 解析二维码
     * @date 2021/1/27 15:51
     * @return java.lang.String
     **/
    public static String readQRcode() throws NotFoundException, IOException {
        MultiFormatReader multiFormatReader = new MultiFormatReader();
        Map hints = new HashMap();
        File file = new File("QRCode.png");
        hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
        BufferedImage bufferedImage = ImageIO.read(file);
        BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage)));
        Result result = multiFormatReader.decode(binaryBitmap, hints);
        System.out.println(result);
        System.out.println("内容 : " + result.getText());
        System.out.println("编码格式 : " + result.getBarcodeFormat());
        return result.toString();
    }
}

运行程序,控制台输出解析结果:

二维码工具类

将上述二维码生成和解析进行封装,并添加带logo的二维码生成

package xyz.liuyou.zxing;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import xyz.liuyou.zxing.utils.QRCodeUtil;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @author liuminkai
 * @version 1.0
 * @datetime 2021/1/27 22:35
 * @decription 二维码工具类
 **/
public class QRCodeUtils {
    /**
     * 字符集
     */
    private static final String CHARSET = "UTF-8";
    /**
     * 二维码尺寸 长宽
     */
    private static final int QRCODE_SIZE = 400;
    /**
     * 生成二维码图片的格式
     */
    private static final String FORMAT = "jpg";
    /**
     * logo宽
     */
    private static final int LOGO_WIDTH = QRCODE_SIZE/5;
    /**
     * logo高
     */
    private static final int LOGO_HEIGHT = QRCODE_SIZE/5;

    /**
     * 设置 二维码 1 代表色 : 默认 0xFF000000 黑
     */
    private static final int ONE_COLOR = 0xFF000001;
//    private static final int ONE_COLOR = 0xFFFF0000; // 红

    /**
     * 设置 二维码 0 代表色 : 默认 0xFFFFFFFF 白
     */
    private static final int ZERO_COLOR = 0xFFFFFFFF;


    public static void createQRCode(String content, String outputPath) throws IOException {
        createQRCode(content, new FileOutputStream(outputPath));
    }

    public static void createQRCode(String content, File outputFile) throws IOException {
        createQRCode(content, new FileOutputStream(outputFile));
    }

    /**
     * 创建原始二维码(不带logo)
     * @param content 二维码内容
     * @param output 二维码(文件)输出流
     * @return void
     **/
    public static void createQRCode(String content, OutputStream output) {
        try {
            ImageIO.write(createQRCodeImage(content), FORMAT, output); // 关键类 ImageIO
            output.close();
        } catch (IOException | WriterException e) {
            e.printStackTrace();
        }
    }

    public static void createQRCodeWithLogo(String content, String outputPath, String logoPath) throws IOException {
        createQRCodeWithLogo(content, new FileOutputStream(outputPath), logoPath, true);
    }

    public static void createQRCodeWithLogo(String content, String outputPath, String logoPath, boolean needCompress) throws IOException {
        createQRCodeWithLogo(content, new FileOutputStream(outputPath), logoPath, needCompress);
    }

    public static void createQRCodeWithLogo(String content, File outputFile, String logoPath, boolean needCompress) throws IOException {
        createQRCodeWithLogo(content, new FileOutputStream(outputFile), logoPath, needCompress);
    }
    /**
     * 创建二维码(带logo)
     * @param content
     * @param output
     * @param logoPath logo路径(可以是resources路径)
     * @param needCompress 是否需要压缩logo
     * @return void
     **/
    public static void createQRCodeWithLogo(String content, OutputStream output, String logoPath, boolean needCompress) {
        try {
            // 创建image对象
            BufferedImage qrcodeImage = createQRCodeImage(content);
            BufferedImage logoImage = createLogoImage(logoPath);
            // 压缩logo
            if(needCompress) {
                logoImage = compressLogoImage(logoImage);
            }
            // 绘制logo二维码
            BufferedImage newImage = drawLogoQRCode(qrcodeImage, logoImage);
            // 生成
            ImageIO.write(newImage, FORMAT, output);
            output.close();
        } catch (WriterException | IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解析qrcode二维码图片
     * @param qrcodePath 二维码路径
     * @return java.lang.String
     * @throw IOException, NotFoundException
     **/
    public static String parseQRCode(String qrcodePath) throws IOException, NotFoundException {
        Map<DecodeHintType, Object> hints = new HashMap<>();
        hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
        BufferedImage image = ImageIO.read(new File(qrcodePath));
        MultiFormatReader multiFormatReader = new MultiFormatReader(); // 主要对象 ===========
        Result result = multiFormatReader.decode(new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image))), hints);
        return result.toString();
    }



    /**
     * (私有)创建二维码图像对象
     * @param content 二维码内容
     * @return java.awt.image.BufferedImage
     * @throw WriterException
     **/
    private static BufferedImage createQRCodeImage(String content) throws WriterException {
        if (content == null) {
            throw new NullPointerException("createQRCodeImage(String content) : content不能为null");
        }
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET); // 字符集
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); // 纠错级别,级别越高存储数据越少
        hints.put(EncodeHintType.MARGIN, 1); // 外边框
        MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); // ====== 主要对象
        BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);// 编码 生成矩阵对象
        MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(ONE_COLOR, ZERO_COLOR); // 配置 二维码颜色
        return MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig); // 生成图像对象(注意要设置颜色,且不能是默认的,不然使用不了rgb绘制图像,也就是黑白色)
    }

    /**
     * (私有)创建logo图像对象
     * @param logoPath
     * @return java.awt.image.BufferedImage
     * @throw IOException
     **/
    private static BufferedImage createLogoImage(String logoPath) throws IOException {
        InputStream is = QRCodeUtil.class.getClassLoader().getResourceAsStream(logoPath);
        if (is == null) {
            is = new FileInputStream(logoPath);
        }
        BufferedImage logoImage = ImageIO.read(is);
        is.close();
        return logoImage; // 关键类 ImageIO
    }

    /**
     * (私有)压缩logo,返回新的logo图像对象 (防止图片过大缩放质量差)
     * @param logoImage
     * @return java.awt.image.BufferedImage
     **/
    private static BufferedImage compressLogoImage(BufferedImage logoImage) {
        // 获取logo原始图片宽高
        int originalHeight = logoImage.getHeight();
        int originalWidth = logoImage.getWidth();
        // 压缩logo (宽高都是选择最小的)
        int height = originalHeight > LOGO_HEIGHT ? LOGO_HEIGHT : originalHeight;
        int width = originalWidth > LOGO_WIDTH ? LOGO_WIDTH : originalWidth;
        // 获取缩放
        Image scaledInstance = logoImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 创建画笔
        Graphics2D graphics = newImage.createGraphics();
        // 绘制压缩后的logo
        graphics.drawImage(scaledInstance, 0, 0, width, height, null);
        graphics.dispose();
        return newImage;
    }

    /**
     * (私有)绘制logo二维码
     * @param qrcodeImage
     * @param logoImage
     * @return void
     **/
    private static BufferedImage drawLogoQRCode(BufferedImage qrcodeImage, BufferedImage logoImage) {
        // 获取画笔对象
        Graphics2D graphics = qrcodeImage.createGraphics();
        int logoX = (QRCODE_SIZE - LOGO_WIDTH) / 2;
        int logoY = (QRCODE_SIZE - LOGO_HEIGHT) / 2;
        // 绘制logo到qrcode上
        graphics.drawImage(logoImage, logoX, logoY, LOGO_WIDTH, LOGO_HEIGHT, null);
        // 绘制logo边框(圆弧框)
        Shape round = new RoundRectangle2D.Float(logoX-2, logoY-2, LOGO_WIDTH+2, LOGO_HEIGHT+2, 10, 10);
        graphics.setStroke(new BasicStroke(5f)); // 宽度
        graphics.setColor(Color.LIGHT_GRAY);
        graphics.draw(round);
        // 销毁画笔
        graphics.dispose();
        return qrcodeImage;
    }

    public static void main(String[] args) throws IOException, WriterException, NotFoundException {
        String content = "中文。。。。。。。。。。。。。。。。。。。。。。。";
        QRCodeUtils.createQRCodeWithLogo(content, "logoqrcode.jpg", "author.jpg");
        QRCodeUtils.createQRCode(content, "qrcode.jpg");
        System.out.println("qrcode.jpg 被解析为:" + parseQRCode("qrcode.jpg"));
        System.out.println("logoqrcode.jpg 被解析为:" + parseQRCode("logoqrcode.jpg"));
    }
}

测试结果展示:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值