智慧农业后台管理
Administrator
2022-06-01 8c6155a0cea4df40a9a6b6c96a845659f8ae0d83
新增溯源码二维码生成
1 files modified
2 files added
408 ■■■■■ changed files
pom.xml 11 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/utils/QRCodeUtil.java 290 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/qrcode/QrCodeController.java 107 ●●●●● patch | view | raw | blame | history
pom.xml
@@ -192,6 +192,17 @@
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <!--  二维码生成  -->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.3.3</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.3.3</version>
        </dependency>
    </dependencies>
    <build>
src/main/java/org/springblade/common/utils/QRCodeUtil.java
New file
@@ -0,0 +1,290 @@
package org.springblade.common.utils;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.itextpdf.xmp.impl.Base64;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import static com.google.zxing.client.j2se.MatrixToImageConfig.BLACK;
import static com.google.zxing.client.j2se.MatrixToImageConfig.WHITE;
/**
 * <p>QRCodeUtil</p>
 *
 * @author lvhaosir6
 * @version 1.0.0
 * @date 2020/7/8
 * @import_date 2021-8-24
 */
@Slf4j
@UtilityClass
public class QRCodeUtil {
    /**
     * 默认宽度
     */
    private static final Integer WIDTH = 140;
    /**
     * 默认高度
     */
    private static final Integer HEIGHT = 140;
    /**
     * LOGO 默认宽度
     */
    private static final Integer LOGO_WIDTH = 22;
    /**
     * LOGO 默认高度
     */
    private static final Integer LOGO_HEIGHT = 22;
    /**
     * 图片格式
     */
    private static final String IMAGE_FORMAT = "png";
    private static final String CHARSET = "utf-8";
    /**
     * 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析
     */
    private static final String BASE64_IMAGE = "data:image/png;base64,%s";
    /**
     * 生成二维码,使用默认尺寸
     *
     * @param content 内容
     * @return
     */
    public String getBase64QRCode(String content) {
        return getBase64Image(content, WIDTH, HEIGHT, null, null, null);
    }
    /**
     * 生成二维码,使用默认尺寸二维码,插入默认尺寸logo
     *
     * @param content 内容
     * @param logoUrl logo地址
     * @return
     */
    public String getBase64QRCode(String content, String logoUrl) {
        return getBase64Image(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT);
    }
    /**
     * 生成二维码
     *
     * @param content    内容
     * @param width      二维码宽度
     * @param height     二维码高度
     * @param logoUrl    logo 在线地址
     * @param logoWidth  logo 宽度
     * @param logoHeight logo 高度
     * @return
     */
    public String getBase64QRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) {
        return getBase64Image(content, width, height, logoUrl, logoWidth, logoHeight);
    }
    private String getBase64Image(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        BufferedImage bufferedImage = crateQRCode(content, width, height, logoUrl, logoWidth, logoHeight);
        try {
            ImageIO.write(bufferedImage, IMAGE_FORMAT, os);
        } catch (IOException e) {
            log.error("[生成二维码,错误{}]", e);
        }
        // 转出即可直接使用
        return String.format(BASE64_IMAGE, Base64.encode(os.toByteArray()));
    }
    /**
     * 生成二维码
     *
     * @param content    内容
     * @param width      二维码宽度
     * @param height     二维码高度
     * @param logoUrl    logo 在线地址
     * @param logoWidth  logo 宽度
     * @param logoHeight logo 高度
     * @return
     */
    private BufferedImage crateQRCode(String content, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) {
        if (StrUtil.isNotBlank(content)) {
            ServletOutputStream stream = null;
            HashMap<EncodeHintType, Comparable> hints = new HashMap<>(4);
            // 指定字符编码为utf-8
            hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
            // 指定二维码的纠错等级为中级
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
            // 设置图片的边距
            hints.put(EncodeHintType.MARGIN, 2);
            try {
                QRCodeWriter writer = new QRCodeWriter();
                BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
                BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                for (int x = 0; x < width; x++) {
                    for (int y = 0; y < height; y++) {
                        bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
                    }
                }
                if (StrUtil.isNotBlank(logoUrl)) {
                    insertLogo(bufferedImage, width, height, logoUrl, logoWidth, logoHeight);
                }
                return bufferedImage;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (stream != null) {
                    try {
                        stream.flush();
                        stream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return null;
    }
    /**
     * 二维码插入logo
     *
     * @param source     二维码
     * @param width      二维码宽度
     * @param height     二维码高度
     * @param logoUrl    logo 在线地址
     * @param logoWidth  logo 宽度
     * @param logoHeight logo 高度
     * @throws Exception
     */
    private void insertLogo(BufferedImage source, Integer width, Integer height, String logoUrl, Integer logoWidth, Integer logoHeight) throws Exception {
        // logo 源可为 File/InputStream/URL
        Image src = ImageIO.read(new URL(logoUrl));
        // 插入LOGO
        Graphics2D graph = source.createGraphics();
        int x = (width - logoWidth) / 2;
        int y = (height - logoHeight) / 2;
        graph.drawImage(src, x, y, logoWidth, logoHeight, null);
        Shape shape = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }
    /**
     * 获取二维码
     *
     * @param content 内容
     * @param output  输出流
     * @throws IOException
     */
    public void getQRCode(String content, OutputStream output) throws IOException {
        BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, null, null, null);
        ImageIO.write(image, IMAGE_FORMAT, output);
    }
    /**
     * 获取二维码
     *
     * @param content 内容
     * @param logoUrl logo资源
     * @param output  输出流
     * @throws Exception
     */
    public void getQRCode(String content, String logoUrl, OutputStream output) throws Exception {
        BufferedImage image = crateQRCode(content, WIDTH, HEIGHT, logoUrl, LOGO_WIDTH, LOGO_HEIGHT);
        ImageIO.write(image, IMAGE_FORMAT, output);
    }
    /**
     *高度——height,
     * 宽度——width,
     * 二维码内容——text(url需要自动跳转前面加上https://)
     */
    public static byte[] getQRCodeImage(String text, int width, int height) throws WriterException, IOException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        HashMap<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        BitMatrix bitMatrix =qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height,hints);
        //删除白边
//        BufferedImage bufferedImage = deleteWhite(bitMatrix);
        //BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height);
        ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "JPG", pngOutputStream);
        //返回
        return pngOutputStream.toByteArray();
    }
    /**
     * 去白边的话,调用这个方法
     * @param matrix
     * @return
     */
    private static BufferedImage  deleteWhite(BitMatrix matrix) {
        int[] rec = matrix.getEnclosingRectangle();
        int resWidth = rec[2] + 1;
        int resHeight = rec[3] + 1;
        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
        resMatrix.clear();
        for (int i = 0; i < resWidth; i++) {
            for (int j = 0; j < resHeight; j++) {
                if (matrix.get(i + rec[0], j + rec[1]))
                    resMatrix.set(i, j);
            }
        }
        int width = resMatrix.getWidth();
        int height = resMatrix.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, resMatrix.get(x, y) ? BLACK
                    : WHITE);
            }
        }
        return image;
    }
//    private static BitMatrix deleteWhite(BitMatrix matrix) {
//        int[] rec = matrix.getEnclosingRectangle();
//        int resWidth = rec[2] + 1;
//        int resHeight = rec[3] + 1;
//
//        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
//        resMatrix.clear();
//        for (int i = 0; i < resWidth; i++) {
//            for (int j = 0; j < resHeight; j++) {
//                if (matrix.get(i + rec[0], j + rec[1]))
//                    resMatrix.set(i, j);
//            }
//        }
//        return resMatrix;
//    }
}
src/main/java/org/springblade/modules/qrcode/QrCodeController.java
New file
@@ -0,0 +1,107 @@
package org.springblade.modules.qrcode;
import com.google.zxing.WriterException;
import lombok.AllArgsConstructor;
import org.springblade.common.utils.QRCodeUtil;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.system.vo.UserVO;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Encoder;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
 * @author zhongrj
 * @date 2021-08-24
 * 二维码生成
 */
@RestController
@RequestMapping("/qrCode")
@AllArgsConstructor
public class QrCodeController {
    private final IUserService userService;
    /**
     * 二维码生成-字节流
     * @param securityNumber 保安证编号
     * @return
     */
    @GetMapping("/getQrCode")
    public ResponseEntity<byte[]> getQrCode(String securityNumber) throws UnsupportedEncodingException {
        String url = "http://61.131.136.25:2080/securityInfo.html";
        if (null!=securityNumber) {
            String encoded = URLEncoder.encode(securityNumber,"UTF-8");
            String content = url + "?securityNumber=" + encoded;
            ResponseEntity<byte[]> aEntity = null;
            try {
                URLEncoder.encode(content,"utf-8");
                byte[] qrCodeImage = QRCodeUtil.getQRCodeImage(content, 350, 350);
                // Set headers
                final HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.IMAGE_PNG);
                aEntity = new ResponseEntity<byte[]>(qrCodeImage, headers, HttpStatus.CREATED);
            } catch (WriterException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return aEntity;
        }
        return null;
    }
    /**
     * 二维码生成base64
     * @param code 溯源码编号
     * @return
     */
    @GetMapping("/getQrCodeBase64")
    public String getQrCodeBase64(String code) throws Exception{
        String url = "http://61.131.136.25:2080/securityInfo.html";
        if (null!=code) {
            String encoded = URLEncoder.encode(code,"UTF-8");
            String content = url + "?code=" + encoded;
            byte[] qrCodeImage = QRCodeUtil.getQRCodeImage(content, 350, 350);
            String encode = new BASE64Encoder().encode(qrCodeImage);
            return "data:image/png;base64,"+encode;
        }
        return null;
    }
    /**
     * 二维码生成base64
     * @param securityNumber 保安证编号
     * @return
     */
    @GetMapping("/getQrCodeDown")
    public String getQrCodeDown(String securityNumber) throws Exception{
//        String url = "http://s16s652780.51mypc.cn/securityInfo/securityInfo.html";
        String url = "http://61.131.136.25:2080/securityInfo.html";
        if (null!=securityNumber) {
            String encoded = URLEncoder.encode(securityNumber,"UTF-8");
            String content = url + "?securityNumber=" + encoded;
            byte[] qrCodeImage = QRCodeUtil.getQRCodeImage(content, 350, 350);
            String path = "D:\\QrCode\\";
            FileOutputStream fileOutputStream = new FileOutputStream(path+securityNumber+".png");
            fileOutputStream.write(qrCodeImage,0,qrCodeImage.length);
            fileOutputStream.flush();
            fileOutputStream.close();
            return securityNumber;
        }
        return null;
    }
}