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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM