項目中咱們常常會用到二維碼,今天就來說講二維碼的生成:
1, 二維碼的概念:
二維條碼/二維碼(2-dimensional bar code)是用某種特定的集合圖形按必定規律在平面(二維方向上)分佈的黑白相間的圖形記錄數據符號信息的圖形.(二維碼的黑點表明二進制的1,空白表明二進制的0);
2, 一維碼(條形碼) 是由一組粗細不一樣,黑白(或彩色)相間的條,空及其相應的字符(數字字母)組成的標記,即傳統條碼.
3, 二維碼分類:
二維碼也有許多不一樣的碼制,就碼制的編碼原理而言,一般分爲三種類型:
(1), 線性堆疊式二維碼;
編碼原理: 創建在一維條形碼基礎之上,按須要堆積成兩行或多行;
(2), 矩陣式二維碼;
最經常使用的類型: 在一個矩形空間經過黑,白像素在矩陣中的不一樣分佈進行編碼. 在矩陣相應元素位置上, 用點(方點,圓點或其餘形狀)的出現表示二進制"1",點的不出現表示二進制的"0";
(3), 郵政碼;
最少使用: 郵政碼經過不一樣長度的條進行編碼,主要用於郵件編碼,如: POSTNET, BPO4-STATE.
4, 二維碼的優缺點:
優勢: (1), 高密度編碼,信息容量大;
(2), 編碼範圍廣;
(3), 容錯能力強;
(4), 譯碼可靠性高;
(5), 可引入加密措施;
(6), 成本低,易製做,持久耐用;
缺點: (1), 二維碼技術成爲手機病毒,釣魚網站傳播的新渠道;
(2), 信息泄露
5, QR code:
目前流行的三大國際標準:
PDF417: 不支持中文;
DM: 專利未公開;
QR code: 專利公開,支持中文;相比其餘二維碼,具備識讀速度快,數據密度大,佔用空間小的優點;
QR code 是由日本Denso公司於1994年研製的一種矩陣二維碼符號嗎,全稱是Quick Response Code.
6, Java生成二維碼:
ZXing Project, QrCode等,這裏主要來測試ZXing的用法:javascript
package code; import java.awt.image.BufferedImage; import java.io.File; import java.nio.file.FileSystems; import java.nio.file.Path; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.regex.Pattern; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import com.google.zxing.BarcodeFormat; import com.google.zxing.BinaryBitmap; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatReader; import com.google.zxing.MultiFormatWriter; import com.google.zxing.Result; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; /** * Maven 倉庫: * <dependency> * <groupId>com.google.zxing</groupId> * <artifactId>javase</artifactId> * <version>3.3.1</version> * </dependency> * * Jar包: * javase-3.3.1.jar; * core-3.3.1.jar; * */ /** *@description TODO 二維碼生成解析類 *@date 2018/1/22 *@author geYang **/ public class QrCode { /** * @description TODO 生成QR_Code圖片 * @param size 生成圖片大小 * @param content 內容 * @param path 生成的地址 * @return String * @date 2018年1月22日下午4:54:28 * @author geYang **/ public static String generateQrCode(Integer size, String content, String path, boolean isQrCode) throws Exception{ String imageName = getNowDate()+".png"; BitMatrix matrix; if(isQrCode){ matrix = generateQrCode(size, content); } else { matrix = generateEna13Code(content); } //生成二維碼圖片: Path file = FileSystems.getDefault().getPath(path, imageName); MatrixToImageWriter.writeToPath(matrix, "png", file); return path+imageName; } /** * @description TODO 生成圖片流 * @author geYang **/ public static void generateQrCode(Integer size, String content, HttpServletResponse response, boolean isQrCode) throws Exception{ BitMatrix matrix; if(isQrCode){ matrix = generateQrCode(size, content); } else { matrix = generateEna13Code(content); } MatrixToImageWriter.writeToStream(matrix, "png", response.getOutputStream()); response.getOutputStream().flush(); response.getOutputStream().close(); } public static BitMatrix generateQrCode(Integer size, String content) throws Exception{ size = (size==null || size<300) ? 300 : size; //定義二維碼參數: HashMap<EncodeHintType, Object> hintType = new HashMap<>(); hintType.put(EncodeHintType.CHARACTER_SET, "utf-8"); //糾錯等級 hintType.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); //二維碼與圖片邊距 hintType.put(EncodeHintType.MARGIN, 2); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hintType); return bitMatrix; } /** * 生成一維碼(條形碼) * @author geYang **/ public static BitMatrix generateEna13Code(String content) throws Exception{ HashMap<EncodeHintType, Object> hintType = new HashMap<>(); hintType.put(EncodeHintType.CHARACTER_SET, "utf-8"); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.EAN_13, 105, 50, hintType); return bitMatrix; } /** * @description TODO 解析二維碼/條形碼 * @return String * @date 2018年1月22日下午5:08:13 * @author geYang * @throws Exception **/ public static String decoder(String path) throws Exception{ MultiFormatReader formatReader = new MultiFormatReader(); File input = new File(path); BufferedImage read = ImageIO.read(input); BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(read))); Result result = formatReader.decode(binaryBitmap); return result.getText(); } /**當前時間*/ private static String getNowDate(){ SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); return sf.format(new Date()); } /** * 百度百科: https://baike.baidu.com/item/%E6%9D%A1%E5%BD%A2%E7%A0%81/278988?fr=aladdin * @description TODO 生成商品條形碼數字內容 * @param 69838 地區代碼:69838 表明中國大陸 * @param shopCode 商品代碼(5位數字) 表明着生產廠商代碼,由廠商申請,國家分配 * @param productCode 商品代碼(4位數字) 表明着廠內商品代碼,由廠商自行肯定 * @return String * @date 2018年1月23日下午2:25:40 * @author geYang **/ public static String getEna13CodeContent(String productCode){ return getEna13CodeContent("69838", productCode); } public static String getEna13CodeContent(String shopCode, String productCode){ Pattern pattern = Pattern.compile("[0-9]*"); StringBuffer code = new StringBuffer("693"); if(shopCode==null || shopCode.trim().length()!=5 || !pattern.matcher(shopCode).matches()){ return null; } if(productCode==null || productCode.trim().length()!=4 || !pattern.matcher(productCode).matches()){ return null; } code.append(shopCode).append(productCode); //奇數位和;偶數位和 int sumA=0, sumB = 0; for(int i=0; i<code.length(); i++){ int j = Integer.parseInt(code.substring(i, i+1)); if((i+1)%2==1){ sumA = sumA + j; } else { sumB = sumB + j; } } code.append((10-((sumA+(sumB*3))%10))%10); return code.toString(); } /** * 測試 * */ public static void main(String[] args) throws Exception { String content = getEna13CodeContent("0003"); System.out.println("生成的條形碼內容:"+content); String codeImage = generateQrCode(300, content, "C:/Users/yvdedu.com/Desktop/IMGS/code/", false); System.out.println("解析的條形碼內容:"+decoder(codeImage)); } }
2, 在 Servlet 中使用:html
package code; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/code") public class QrCodeServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { QrCode.generateQrCode(300, "http://www.baidu.com", response, true); } catch (Exception e) { e.printStackTrace(); } } }
3, jQuery生成二維碼:java
<%@ page contentType="text/html; charset=UTF-8" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8" http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>生成二維碼</title> <!-- 二維碼生成工具 --> <script type="text/javascript" src="<%=request.getContextPath()%>/js/jquery.min.js"></script> <script type="text/javascript" src="<%=request.getContextPath()%>/js/jquery.qrcode.min.js"></script> </head> <body> <!-- 生成二維碼方法: --> <div id="qrcode"></div> <script type="text/javascript"> jQuery("#qrcode").qrcode("Hellow jQuery QR_Code") </script> </body> </html>
Java生成二維碼就這麼簡單,推薦使用jQuery來生成二維碼(比較簡單);jquery