基础知识spring boot

54 java生成QR二维码

2019-01-17  本文已影响58人  滔滔逐浪

引言
随着二维码(QR code)的普及,越来越多的项目中会设计一些产生二维码的交互页面,以便更好地和用户互动,以及方便用户的使用,传播app等操作。那么今天就来探究一下如何在项目中快速简单的生成QR二维码。

一.简易版本
首先
我们用到谷歌开源的zxing项目包,使用maven的同学可以轻易的导入。

<!--QRcode-->
        <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>
        <!--QRcode-->

第二步
我们来编写生成简单二维码的java代码。只要有一个content的输入,能把content的内容藏到二维码中即可。那么代码如下:

package com.yuqiyu.schoolcms.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import java.awt.image.BufferedImage;
import java.util.Hashtable;

public class QRCodeUtil {
      private  static final String CHARSET ="utf-8";
      //二维码尺寸
    private  static final int QRCODE_SIZE=300;
    public static BufferedImage createImage(String content){
    Hashtable<EncodeHintType,Object> hints =new Hashtable<EncodeHintType, Object>();
      hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
      hints.put(EncodeHintType.CHARACTER_SET,CHARSET);
        hints.put(EncodeHintType.MARGIN,1);
        BitMatrix bitMatrix =null;
        try{
            bitMatrix =new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,QRCODE_SIZE,QRCODE_SIZE,
                   hints );
        }catch (Exception e){
            e.printStackTrace();
        }
        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);
            }
        }
        return image;
    }
}

下面我们编写controller接口去进行测试

注意:对于有些二维码是扫了即用,扫完即走那种的,这个时候就不应该产生本地的缓存暂用服务器资源。禁止缓存的方式详见代码

package com.yuqiyu.schoolcms.controller;

import com.yuqiyu.schoolcms.utils.QRCodeUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

@RestController
public class QRController {
@RequestMapping("/generateQR")
 public void generateQR(@RequestParam("content")String content, HttpServletResponse response){
        BufferedImage image;
        //禁止图像缓存
        response.setHeader("pragma","No-cache");

  response.setHeader("Cache-control","no-cache");
        response.setDateHeader("Expires",0);
         response.setContentType("image/jpeg");

         image= QRCodeUtil.createImage(content);
      //创建二进制的输出流
        try(ServletOutputStream sos = response.getOutputStream()){
            // 将图像输出到Servlet输出流中。
            ImageIO.write(image, "jpeg", sos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

访问网址 http://localhost:8084/generateQR?content=1

二.拓展版本
在实际中,我们常常会看见一些二维码中间会放置上企业的logo,显得更加的美观专业。接下来我们就如何在二维码中间增加图案进行说明。

首先
我们考虑增加两个变量,一个是插入图片的地址,一个压缩参数(主要用于过大logo情况下是否压缩)

// LOGO宽度
    private static final int LOGO_WIDTH = 80;
    // LOGO高度
    private static final int LOGO_HEIGHT = 80;
    /**
     * 插入LOGO
     *
     * @param source       二维码图片
     * @param logoPath     LOGO图片地址
     * @param needCompress 是否压缩
     * @throws Exception
     */
    public static void insertImage(BufferedImage source, InputStream logoPath, boolean needCompress)  {
        Image src = null;
        try {
            src = ImageIO.read(logoPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        if (needCompress) {
            // 压缩LOGO
            if (width > LOGO_WIDTH) {
                width = LOGO_WIDTH;
            }
            if (height > LOGO_HEIGHT) {
                height = LOGO_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, 12, 12);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }

我们只要在一中生成图片的基础上调用该方法,即可在里面插入一个Logo。

接着
我们照样编写了controller去测试:
@RequestMapping("/generateQRzengqiang")
public void generateQRzengqiang(@RequestParam("content")String content, HttpServletResponse response){
    BufferedImage image;
    //禁止图像缓存
    response.setHeader("pragma","No-cache");
 response.setHeader("Cache-control","no-cache");
    response.setDateHeader("Expires",0);
    response.setContentType("image/jpeg");

    image= QRCodeUtil.createImage(content);
 InputStream inputStream=this.getClass().getResourceAsStream("/static/1.jpg"); //新增代码
    QRCodeUtil.insertImage(image,inputStream,Boolean.TRUE);//新增代码
    //创建二进制的输出流
    try(ServletOutputStream sos = response.getOutputStream()){

 // 将图像输出到Servlet输出流中。
        ImageIO.write(image, "jpeg", sos);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

上一篇下一篇

猜你喜欢

热点阅读