Java二维码的生成以及附加Logo

Java二维码的生成以及附加Logo

生成二维码

所需依赖

生成二维码需要借助Zxing包

        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.3.0</version>
        </dependency>

实现过程

  1. 创建一个QRCodeWriter
  2. 使用QRCodeWriter的encode方法生成BitMatrix对象
  3. 下面分两种情况
    1. 如果需要转成流在页面展示或者下载,借助MatrixToImageWriter的writeToStream()方法将BitMatrix写到输出流
    2. 如果需要导出为文件,借助MatrixToImageWriter的writeToPath()方法将BitMatrix写到路径
写入到输出流
    public static byte[] getQrCodeImageForByte(String text, int width, int height) throws WriterException, IOException {
        //设置参数,用来处理信息中的中文问题
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        //获取二维码
        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height,hints);
        //定义输出流并将二维码写入到输出流
        ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "PNG", pngOutputStream);
        return pngOutputStream.toByteArray();
    }
写入到路径
    public static void getQrCodeImageForFile(String text,String filePath,int width,int height) throws WriterException, IOException {
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height,hints);
		//将二维码写入到路径
        Path path = FileSystems.getDefault().getPath(filePath);
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
    }

生成带logo的二维码

基本原理为将BitMatrix对象转换成BufferedImage对象,然后在该对象上进行修改

基本参数定义
    /**
     * 二维码尺寸
     **/
    private static final int QRCODE_SIZE = 300;
    /**
     * LOGO宽度
     **/
    private static final int WIDTH = 60;
    /**
     * LOGO高度
     **/
    private static final int HEIGHT = 60;
创建二维码
    private static BufferedImage createImage(String content) {
        //设置参数
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        BufferedImage image = null;
        try {

            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
                    hints);
            int width = bitMatrix.getWidth();
            int height = bitMatrix.getHeight();
            //定义BufferedImage对象并将BitMatrix对象的像素一一对应
            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);
                }
            }
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return image;
    }
插入logo
 private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) {
     	//对logo文件进行判断
        Optional.ofNullable(imgPath).orElseThrow(NullPointerException::new);
        File file = new File(imgPath);
        if (!file.exists()) {
            System.err.println("" + imgPath + "   该文件不存在!");
            return;
        }
        Image src ;
        try {
            src = ImageIO.read(new File(imgPath));
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        // needCompress属性用来标识是否要对logo文件压缩
        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;
        }
        // 插入LOGO
        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();
    }
将BufferedImage转成byte流

这里只展示转成byte流,如果想转成文件保存,使用ImageIO.write()方法将BufferedImage写入到File对象就可以

    private static byte[] convertBufferedImageIntoBytes(BufferedImage source) {
        ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
        try {

            ImageIO.write(source, "PNG", pngOutputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return pngOutputStream.toByteArray();
    }
封装出public方法供外部类使用
    //获取带logo的二维码
	public static byte[] encode(String content, String imgPath, boolean needCompress) {
        BufferedImage image = QrCodeGeneratorDemo2.createImage(content);
        insertImage(image, imgPath, needCompress);
        return convertBufferedImageIntoBytes(image);
    }
	//只获取二维码
    public static byte[] encode(String content) {
        BufferedImage image = QrCodeGeneratorDemo2.createImage(content);
        return convertBufferedImageIntoBytes(image);
    }
测试用例

使用两个接口分别测试只获取二维码和获取带logo的二维码

@RestController
public class TestController {
    @GetMapping("/getCode")
    public ResponseEntity<byte[]> createQrCode() throws Exception {
        String text="只展示二维码";
        byte[] image = QrCodeGeneratorDemo2.encode(text);
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "image/png");
        return new ResponseEntity<>(image,responseHeaders, HttpStatus.OK) ;
    }
    @GetMapping("/getCodeWithLogo")
    public ResponseEntity<byte[]> createQrCodeWithLogo() throws Exception {
        // 存放在二维码中的内容
        String text = "展示带logo的二维码";
        // 嵌入二维码的图片路径
        String imgPath = "D:\\田园犬.png";
        byte[] image = QrCodeGeneratorDemo2.encode(text, imgPath, true);
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "image/png");
        return new ResponseEntity<>(image,responseHeaders, HttpStatus.OK) ;
    }
}
效果展示

只展示二维码

image-20210512160748281

展示带logo的二维码

image-20210512160929096

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值