zoukankan      html  css  js  c++  java
  • java实现二维码的生成与解析

    二维码的生成及解析的低层实现并不简单,我们只需要知道怎么使用就可以了,参考博客:https://blog.csdn.net/jam_fanatic/article/details/82818857

    1.maven中jar包引用com.google.zxing;

    2.创建QRCodeUtil二维码工具类,使用谷歌提供的帮助类BufferedImageLuminanceSource绘制二维码。

      生成二维码:QRCodeUtil.encode(编码到二维码中的内容, 嵌入二维码的图片路径, 生成的二维码的存放路径, 图片是否进行压缩);

      解析二维码:QRCodeUtil.decode(要解析的二维码的存放路径);

      注意事项:如果你想让别人扫描后跳转一个页面的话,直接在编码的方法里,将编码内容改为一个地址就可以了,这样别人扫描二维码后会自动跳转。二维码存的信息越多,二维码图片也就越复杂,容错率也就越低,识别率也越低,并且二维码能存的内容大小也是有限的(大概500个汉字左右)

      1 package com.gsafety.consumer.util;
      2 
      3 import java.awt.Graphics;
      4 import java.awt.Graphics2D;
      5 import java.awt.Image;
      6 import java.awt.Shape;
      7 import java.awt.geom.RoundRectangle2D;
      8 import java.awt.image.BufferedImage;
      9 import java.io.File;
     10 import java.io.OutputStream;
     11 import java.util.Hashtable;
     12 
     13 import javax.imageio.ImageIO;
     14 
     15 import com.google.zxing.BarcodeFormat;
     16 import com.google.zxing.BinaryBitmap;
     17 import com.google.zxing.DecodeHintType;
     18 import com.google.zxing.EncodeHintType;
     19 import com.google.zxing.MultiFormatReader;
     20 import com.google.zxing.MultiFormatWriter;
     21 import com.google.zxing.Result;
     22 import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
     23 import com.google.zxing.common.BitMatrix;
     24 import com.google.zxing.common.HybridBinarizer;
     25 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
     26 
     27 import lombok.extern.slf4j.Slf4j;
     28 
     29 /**
     30  *   二维码工具类  
     31  */
     32 @Slf4j
     33 public class QRCodeUtil {
     34     
     35     
     36     
     37     private static final String CHARSET = "utf-8";
     38     private static final String FORMAT_NAME = "JPG";
     39     // 二维码尺寸
     40     private static final int QRCODE_SIZE = 250;
     41     // LOGO宽度
     42     private static final int WIDTH = 50;
     43     // LOGO高度
     44     private static final int HEIGHT = 50;
     45     static SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(0,0);
     46     private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {
     47         Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
     48         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
     49         hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
     50         hints.put(EncodeHintType.MARGIN, 0);
     51         BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
     52                 hints);
     53         int width = bitMatrix.getWidth();
     54         int height = bitMatrix.getHeight();
     55         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
     56         for (int x = 0; x < width; x++) {
     57             for (int y = 0; y < height; y++) {
     58                 image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
     59             }
     60         }
     61         if (imgPath == null || "".equals(imgPath)) {
     62             return image;
     63         }
     64         // 插入图片
     65         QRCodeUtil.insertImage(image, imgPath, needCompress);
     66         return image;
     67     }
     68     /**
     69      *  插入LOGO          
     70      * @param source    二维码图片    
     71      * @param imgPath  LOGO图片地址    
     72      * @param needCompress   是否压缩    
     73      * @throws Exception    
     74      */
     75     private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {
     76         File file = new File(imgPath);
     77         if (!file.exists()) {
     78             log.info("{}该文件不存在!",imgPath);
     79             return;
     80         }
     81         Image src = ImageIO.read(new File(imgPath));
     82         int width = src.getWidth(null);
     83         int height = src.getHeight(null);
     84         if (needCompress) { // 压缩LOGO
     85             if (width > WIDTH) {
     86                 width = WIDTH;
     87             }
     88             if (height > HEIGHT) {
     89                 height = HEIGHT;
     90             }
     91             Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
     92             BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
     93             Graphics g = tag.getGraphics();
     94             g.drawImage(image, 0, 0, null); // 绘制缩小后的图
     95             g.dispose();
     96             src = image;
     97         }
     98         // 插入LOGO
     99         Graphics2D graph = source.createGraphics();
    100         int x = (QRCODE_SIZE - width) / 2;
    101         int y = (QRCODE_SIZE - height) / 2;
    102 //        graph.setClip(new RoundRectangle2D.Double(0, 0, width, height, 90, 90));
    103         graph.drawImage(src, x, y, width, height, null);
    104         Shape shape = new RoundRectangle2D.Float(x, y, width, width, 90,90);
    105 //        graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    106 //        graph.setStroke(new BasicStroke(-1f));
    107         graph.draw(shape);
    108         graph.dispose();
    109     }
    110 
    111     /**
    112      *    
    113      *  生成二维码(内嵌LOGO)   
    114      *  @param content   内容    
    115      *  @param imgPath   LOGO地址   
    116      *  @param destPath  存放目录    
    117      *  @param needCompress   是否压缩LOGO    
    118      *  @throws Exception    
    119      */
    120     
    121     public static String encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
    122         BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
    123         mkdirs(destPath);
    124         String random = snowflakeIdWorker.nextId();
    125         String file = random + ".jpg";
    126         ImageIO.write(image, FORMAT_NAME, new File(destPath + "/" + file));
    127         return "/consumer_qrcode/"+file;
    128     }
    129 
    130     /**
    131      *  当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)    
    132      * @author  
    133       * @date 2013-12-11 上午10:16:36
    134      * @param destPath 存放目录    
    135      */
    136     public static void mkdirs(String destPath) {
    137         File file = new File(destPath);
    138         // 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
    139         if (!file.exists() && !file.isDirectory()) {
    140             file.mkdirs();
    141         }
    142     }
    143 
    144     /**
    145      *     
    146      *  生成二维码(内嵌LOGO)         
    147      *  @param content  内容    
    148      *  @param imgPath  LOGO地址     
    149      *  @param destPath  存储地址   
    150      *  @throws Exception    
    151      */
    152     public static void encode(String content, String imgPath, String destPath) throws Exception {
    153         QRCodeUtil.encode(content, imgPath, destPath, false);
    154     }
    155 
    156     /**
    157      *   
    158      *   生成二维码     
    159      *  @param content   内容    
    160      *  @param destPath  存储地址   
    161      *  @param needCompress   是否压缩LOGO    
    162      *  @throws Exception    
    163      */
    164     public static void encode(String content, String destPath, boolean needCompress) throws Exception {
    165         QRCodeUtil.encode(content, null, destPath, needCompress);
    166     }
    167 
    168     /**
    169      *     
    170      *  生成二维码  
    171      * @param content   内容    
    172      * @param destPath  存储地址    
    173      * @throws Exception    
    174      */
    175     public static void encode(String content, String destPath) throws Exception {
    176         QRCodeUtil.encode(content, null, destPath, false);
    177     }
    178 
    179     /**
    180      *     
    181      *   生成二维码(内嵌LOGO)     
    182      *  @param content  内容     
    183      *  @param imgPath  LOGO地址    
    184      *  @param output   输出流    
    185      *  @param needCompress  是否压缩LOGO    
    186      *  @throws Exception    
    187      */
    188     public static void encode(String content, String imgPath, OutputStream output, boolean needCompress)
    189             throws Exception {
    190         BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
    191         ImageIO.write(image, FORMAT_NAME, output);
    192     }
    193 
    194     /**
    195      *    
    196      *  生成二维码    
    197      *  @param content  内容    
    198      *  @param output   输出流
    199      *  @throws Exception    
    200      */
    201     public static void encode(String content, OutputStream output) throws Exception {
    202         QRCodeUtil.encode(content, null, output, false);
    203     }
    204 
    205     /**
    206      *     
    207      *   解析二维码     
    208      *   @param file 二维码图片     
    209      *   @return    
    210      *   @throws
    211      * Exception    
    212      */
    213     public static String decode(File file) throws Exception {
    214         BufferedImage image;
    215         image = ImageIO.read(file);
    216         if (image == null) {
    217             return null;
    218         }
    219         BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
    220         BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    221         Result result;
    222         Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
    223         // 解码设置编码方式为:utf-8,
    224         hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
    225         //优化精度
    226         hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
    227         //复杂模式,开启PURE_BARCODE模式
    228         hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
    229         result = new MultiFormatReader().decode(bitmap, hints);
    230         
    231         String resultStr = result.getText();
    232         return resultStr;
    233     }
    234 
    235     /**
    236      *    
    237      * 
    238      *  解析二维码      
    239      * @param   path   二维码图片地址    
    240      * @return    
    241      * @throws  Exception    
    242      */
    243     public static String decode(String path) throws Exception {
    244         return QRCodeUtil.decode(new File(path));
    245     }
    246     
    247     public static void main(String[] args) throws Exception {
    248         String text = "爱你一万年"; // 二维码内容
    249          String logoPath = "D:\work\二维码.png"; //嵌入二维码的图片路径
    250         String destPath = "D:\work";//生成二维码的地址
    251         QRCodeUtil.encode(text, logoPath, destPath, false);//生成二维码
    252 //        String decode = QRCodeUtil.decode("D:\work/659518998202810368.jpg");//解析二维码
    253 //        System.out.println(decode);//答应解析二维码的内容
    254     }
    255 }
    View Code

    待补充。。。

      微信支付二维码:https://www.cnblogs.com/xu-xiang/p/5797575.html

      支付宝支付二维码:https://www.cnblogs.com/xu-xiang/p/5797643.html

  • 相关阅读:
    day09 小练习 斐波那契数列 文件
    day09三目运算
    day08文件操作
    Nginx 内容缓存及常见参数配置
    阿里开源分布式事务解决方案 Fescar 全解析
    为什么你学不会递归?刷题几个月,告别递归,谈谈我的经验
    JavaScript 复杂判断的更优雅写法
    Java 线程本地 ThreadLocal 的分析和总结
    总结异步编程的六种方式
    JAVA8新特性(吐血整理)
  • 原文地址:https://www.cnblogs.com/skj0330insn/p/12099464.html
Copyright © 2011-2022 走看看