zoukankan      html  css  js  c++  java
  • 实现二维码且二维码中加logo图片,工作记录,供大家借鉴

    一.准备步骤

      1.1 pom.xml

        <!-- 二维码 https://mvnrepository.com/artifact/com.google.zxing/core -->
            <dependency>
                <groupId>com.google.zxing</groupId>
                <artifactId>core</artifactId>
                <version>3.3.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
            <dependency>
                <groupId>com.google.zxing</groupId>
                <artifactId>javase</artifactId>
                <version>3.3.0</version>
            </dependency>

    1.2 准备一张logo图片,我的图片是服务器上的:http://xxx.xxx.xxx.xx:xxxx//qrCodeImg/logo.png

     1.3 接口源码

      1 package com.web.kds.hadoop_kafka.Controller;
      2 
      3 import java.awt.BasicStroke;
      4 import java.awt.Color;
      5 import java.awt.Graphics2D;
      6 import java.awt.RenderingHints;
      7 import java.awt.image.BufferedImage;
      8 import java.io.ByteArrayInputStream;
      9 import java.io.ByteArrayOutputStream;
     10 import java.io.File;
     11 import sun.misc.BASE64Decoder;
     12 import java.io.IOException;
     13 import java.io.InputStream;
     14 import java.net.URL;
     15 import java.net.URLConnection;
     16 import java.text.SimpleDateFormat;
     17 import java.util.Date;
     18 import java.util.Hashtable;
     19 import java.util.UUID;
     20 
     21 import javax.imageio.ImageIO;
     22 import javax.servlet.ServletOutputStream;
     23 import javax.servlet.http.HttpServletRequest;
     24 import javax.servlet.http.HttpServletResponse;
     25 
     26 import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
     27 import org.springframework.util.StringUtils;
     28 import org.springframework.web.bind.annotation.PostMapping;
     29 import org.springframework.web.bind.annotation.RequestBody;
     30 import org.springframework.web.bind.annotation.RequestMapping;
     31 import org.springframework.web.bind.annotation.RequestParam;
     32 import org.springframework.web.bind.annotation.ResponseBody;
     33 import org.springframework.web.bind.annotation.RestController;
     34 import org.springframework.web.multipart.MultipartFile;
     35 import org.springframework.web.multipart.MultipartHttpServletRequest;
     36 
     37 import com.google.zxing.BarcodeFormat;
     38 import com.google.zxing.EncodeHintType;
     39 import com.google.zxing.MultiFormatWriter;
     40 import com.google.zxing.WriterException;
     41 import com.google.zxing.client.j2se.MatrixToImageWriter;
     42 import com.google.zxing.common.BitMatrix;
     43 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
     44 
     45 import sun.misc.BASE64Encoder;
     46 
     47 @RestController
     48 @RequestMapping("qrcode")
     49 public class QrCodeController {
     50     private static final int BLACK = 0xFF000000;
     51     private static final int WHITE = 0xFFFFFFFF;
     52     private static final int margin = 0;
     53     private static final int LogoPart = 4;
     54     private static final String logoPath ="http://xxx.xxx.xxx.xx:8081//qrCodeImg/logo.png";
     55 
     56 
     57     @RequestMapping("getfile")
     58     public void getQrCodeFile(HttpServletResponse resp) throws Exception {
     59         ServletOutputStream stream = resp.getOutputStream();;
     60         String content = "www.baidu.com";
     61         int width = 260;
     62         int height = 260;
     63         BitMatrix bitMatrix = setBitMatrix(content, width, height);
     64         
     65         BufferedImage image = toBufferedImage(bitMatrix);
     66         // 加入LOGO水印效果
     67         if (logoPath!=null &&!logoPath.equals("")) {
     68             image = addLogo(image, logoPath);
     69         }
     70         // 可通过输出流输出到页面,也可直接保存到文件
     71         ImageIO.write(image, "png", resp.getOutputStream());
     72     }
     73     /**
     74      * 生成二维码矩阵信息
     75      * @param content 二维码图片内容
     76      * @param width 二维码图片宽度
     77      * @param height 二维码图片高度
     78      */
     79     public static BitMatrix setBitMatrix(String content, int width, int height){
     80         Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
     81         hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 指定编码方式,防止中文乱码
     82         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 指定纠错等级
     83         hints.put(EncodeHintType.MARGIN, margin); // 指定二维码四周白色区域大小
     84         BitMatrix bitMatrix = null;
     85         try {
     86             bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
     87         } catch (WriterException e) {
     88             e.printStackTrace();
     89         }
     90         return bitMatrix;
     91     }
     92 
     93 
     94 
     95     /**
     96      * 生成二维码图片  去白边
     97      * @param matrix 二维码矩阵信息
     98      */
     99     public static BufferedImage toBufferedImage(BitMatrix matrix) {
    100         int width = matrix.getWidth();
    101         int height = matrix.getHeight();
    102         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
    103         for (int x = 0; x < width; x++) {
    104             for (int y = 0; y < height; y++) {
    105                 image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
    106             }
    107         }
    108         return image;
    109     }
    110     /**
    111      * 在二维码图片中添加logo图片
    112      * @param image 二维码图片
    113      * @param logoPath logo图片路径
    114      * @throws IOException 
    115      */
    116     public static BufferedImage addLogo(BufferedImage image, String logoPath) throws IOException{
    117         BASE64Decoder base64de = new BASE64Decoder();
    118         Graphics2D g = image.createGraphics();
    119         //消除文字锯齿
    120         g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    121         //消除画图锯齿
    122         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    123 
    124         //把Base64编码过的字节数组字符串解码转换成字节数组
    125         byte[] b= base64de.decodeBuffer(downloadFile(logoPath));
    126         //将字节数组转化为输入流
    127         InputStream   is=new ByteArrayInputStream(b);
    128         //将图片流写入ImageIO流
    129         BufferedImage logoImage = ImageIO.read(is);
    130         // 计算logo图片大小,可适应长方形图片,根据较短边生成正方形
    131         int width = image.getWidth() < image.getHeight() ? image.getWidth() / LogoPart : image.getHeight() / LogoPart;
    132         int height = width;
    133         // 计算logo图片放置位置
    134         int x = (image.getWidth()-width)/ 2;
    135         int y = (image.getHeight()-height)/ 2;
    136         int x1 = (image.getWidth()-width-10)/ 2;
    137         int y1 = (image.getHeight()-height-10)/ 2;
    138         // 边框颜色
    139         g.setColor(Color.white);
    140         // 画笔粗细
    141         g.setStroke(new BasicStroke(5)); // 画笔粗细
    142         //画图层,作用是在logo图片周围加点白边,显示更美观
    143         g.fillRect(x1, y1, width+10, height+10);
    144         //绘制logo边框,
    145         g.drawRoundRect(x1, y1, width+10,height+10, 30, 30);
    146 
    147         // 在二维码图片上绘制logo图片
    148         g.drawImage(logoImage, x, y, width, height, null);
    149         logoImage.flush();
    150         g.dispose();
    151         return image;
    152     }
    153     //将网络图片转base64
    154     public static String downloadFile(String urlPath){
    155         ByteArrayOutputStream data = new ByteArrayOutputStream();  
    156         try {
    157             // 打开图片路径
    158             URL url = new URL(urlPath);
    159             URLConnection connection = url.openConnection();
    160             // 通过输入流获取图片数据
    161             InputStream in = connection.getInputStream();
    162             byte[] by = new byte[1024];
    163             // 将内容读取内存中
    164             int len = -1;
    165             while ((len = in.read(by)) != -1) {
    166                 data.write(by, 0, len);
    167             }
    168             //关闭流
    169             in.close();     
    170         } catch (IOException e) {
    171             e.printStackTrace();
    172         }
    173         // 返回Base64编码过的字节数组字符串
    174         BASE64Encoder encoder = new BASE64Encoder();     
    175         return encoder.encode(data.toByteArray());
    176     }
    177 
    178 }

     二.效果图:http://localhost:8080/qrcode/getfile

  • 相关阅读:
    什么是test-time argument(测试数据增强)
    在k3d上快速安装Istio,助你在本地灵活使用K8S!
    IoT设备实践丨如果你也在树莓派上部署了k3s,你也许需要这篇文章
    k3s原理分析丨如何搞定k3s node注册失败问题
    仅需60秒,使用k3s创建一个多节点K8S集群!
    手把手实操教程!使用k3s运行轻量级VM
    k3s首季在线培训来袭!本周四晚,线上见!
    k3s新版本发布!支持Helm3!还有其他重要更新Highlight!
    如何优雅地使用containerd?这里有一份必读的技巧攻略
    图解拥塞控制,这应该是把拥塞控制讲的最通俗易懂的文章了
  • 原文地址:https://www.cnblogs.com/KdeS/p/11797001.html
Copyright © 2011-2022 走看看