本文是學習慕課網課程《Java生成二維碼》(http://www.imooc.com/learn/531)的筆記。
一、二維碼的分類
線性堆疊式二維碼、矩陣式二維碼、郵政碼。
二、二維碼的優缺點
優點:1. 高密度編碼,信息容量大;2.編碼范圍廣;3.容錯能力強;4.譯碼可靠性高;5.可引入加密措施;6.成本低,易制作,持久耐用。
缺點:1.二維碼技術成為手機病毒、釣魚網站傳播的新渠道;2.信息容易泄露。
三、三大國際標准
1.PDF417:不支持中文;
2.DM:專利未公開,需要支付專利費用;
3.QR Code:專利公開,支持中文。
其中,QR Code具有識讀速度快、數據密度大、占用空間小的優勢。
四、糾錯能力
L級:約可糾錯7%的數據碼字
M級:約可糾錯15%的數據碼字
Q級:約可糾錯25%的數據碼字
H級:約可糾錯30%的數據碼字
五、ZXing生成/讀取二維碼
首先,下載ZXing源文件。下載地址:https://github.com/zxing/zxing/releases;
再次,創建一個Java項目。將ZXing源文件中的core/src/main/java/com和javase/src/main/java/com兩個文件復制到項目中,編譯成jar文件;
最后,在以后的開發中就可以使用該jar文件。
ZXing生成二維碼的代碼如下:
1 import java.io.File; 2 import java.nio.file.Path; 3 import java.util.HashMap; 4 5 import com.google.zxing.BarcodeFormat; 6 import com.google.zxing.EncodeHintType; 7 import com.google.zxing.MultiFormatWriter; 8 import com.google.zxing.WriterException; 9 import com.google.zxing.client.j2se.MatrixToImageWriter; 10 import com.google.zxing.common.BitMatrix; 11 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 12 13 //生成二維碼 14 public class CreateQRCode { 15 16 public static void main(String[] args) { 17 int width = 300; //二維碼寬度 18 int height = 300; //二維碼高度 19 String format = "png"; //二維碼圖片格式 20 String content = "www.baidu.com"; //二維碼內容 21 22 //定義二維碼參數 23 HashMap hints = new HashMap(); 24 hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); //定義內容字符集的編碼 25 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); //定義糾錯等級 26 hints.put(EncodeHintType.MARGIN, 2); //邊框空白 27 28 try { 29 BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height); 30 31 Path file = new File("E:/img.png").toPath(); 32 33 MatrixToImageWriter.writeToPath(bitMatrix, format, file); 34 //MatrixToImageWriter.writeToStream(bitMatrix, format, stream); 35 36 } catch (Exception e) { 37 e.printStackTrace(); 38 } 39 } 40 }
ZXing讀取二維碼信息的代碼如下:
1 import java.awt.image.BufferedImage; 2 import java.io.File; 3 import java.io.IOException; 4 import java.util.HashMap; 5 6 import javax.imageio.ImageIO; 7 8 import com.google.zxing.Binarizer; 9 import com.google.zxing.BinaryBitmap; 10 import com.google.zxing.EncodeHintType; 11 import com.google.zxing.LuminanceSource; 12 import com.google.zxing.MultiFormatReader; 13 import com.google.zxing.NotFoundException; 14 import com.google.zxing.Result; 15 import com.google.zxing.client.j2se.BufferedImageLuminanceSource; 16 import com.google.zxing.common.BitArray; 17 import com.google.zxing.common.BitMatrix; 18 import com.google.zxing.common.HybridBinarizer; 19 20 public class ReadQRCode { 21 22 public static void main(String[] args) { 23 24 try { 25 MultiFormatReader formatReader = new MultiFormatReader(); 26 27 File file = new File("E:/img.png"); 28 29 BufferedImage image = ImageIO.read(file); //讀取此文件識別成一個圖片 30 31 BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image))); 32 33 //定義二維碼參數 34 HashMap hints = new HashMap(); 35 hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); //定義內容字符集的編碼 36 37 38 Result result = formatReader.decode(binaryBitmap,hints); 39 40 System.out.println("解析結果:" + result.toString()); 41 System.out.println("二維碼格式類型:" + result.getBarcodeFormat()); 42 System.out.println("二維碼文本內容:" + result.getText()); 43 } catch (Exception e) { 44 e.printStackTrace(); 45 } 46 } 47 }
六、QRCode生成/讀取二維碼
QRCode生成和讀取二維碼的jar是分開的,下載網址如下:
QRCode生成二維碼網址:http://swetake.com/qrcode/index-e.html
QRCode讀取二維碼網址:https://osdn.jp/projects/qrcode (此網站無法下載到jar文件)
(后面我在網上搜到一個包含生成和讀取二維碼功能的jar文件,下載路徑:https://files.cnblogs.com/files/bigroc/QRCode.zip)
QRCode生成二維碼代碼如下:
1 import java.awt.Color; 2 import java.awt.Graphics2D; 3 import java.awt.image.BufferedImage; 4 import java.io.File; 5 import java.io.IOException; 6 import java.io.UnsupportedEncodingException; 7 8 import javax.imageio.ImageIO; 9 10 import com.swetake.util.Qrcode; 11 12 //生成二維碼 13 public class CreateQRCode { 14 15 public static void main(String[] args) throws IOException { 16 17 //計算二維碼圖片的高寬比 18 //API文檔規定計算圖片寬高的方式,v是版本號(1~40) 19 int v = 7; 20 int width = 67 + 12 * (v - 1); //計算公式 21 int height = 67 + 12 * (v - 1); 22 23 Qrcode x = new Qrcode(); 24 25 /** 26 * 糾錯等級分為 27 * level L : 最大 7% 的錯誤能夠被糾正; 28 * level M : 最大 15% 的錯誤能夠被糾正; 29 * level Q : 最大 25% 的錯誤能夠被糾正; 30 * level H : 最大 30% 的錯誤能夠被糾正; 31 */ 32 x.setQrcodeErrorCorrect('L'); //設置糾錯等級 33 x.setQrcodeEncodeMode('B'); //N代表數字 A代表a-Z B代表其他字符 34 x.setQrcodeVersion(v); //版本號(1~40) 35 String qrData = "http://www.baidu.com"; //內容信息 36 37 //緩沖區 38 BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 39 40 //繪圖 41 Graphics2D gs = bufferedImage.createGraphics(); 42 43 gs.setBackground(Color.WHITE); //背景色 44 gs.setColor(Color.black); 45 gs.clearRect(0, 0, width, height); //清除畫板內容 46 47 //偏移量 2或7 48 int pixoff = 2; 49 50 /** 51 * 1.注意for循環里面的i,j的順序, 52 * s[j][i]二維數組的j,i的順序要與這個方法中的 gs.fillRect(j*3+pixoff,i*3+pixoff, 3, 3); 53 * 順序匹配,否則會出現解析圖片是一串數字 54 * 2.注意此判斷if (d.length > 0 && d.length < 120) 55 * 是否會引起字符串長度大於120導致生成代碼不執行,二維碼空白 56 * 根據自己的字符串大小來設置此配置 57 */ 58 //把要填充的內容轉化成字節數 59 byte[] d = qrData.getBytes("utf-8"); //漢字轉化格式 60 if (d.length > 0 && d.length < 120) { 61 boolean[][] s = x.calQrcode(d); 62 63 for (int i = 0; i < s.length; i++) { 64 for (int j = 0; j < s.length; j++) { 65 if (s[j][i]) { 66 //把d中的內容填充 67 gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3); 68 } 69 } 70 } 71 } 72 73 gs.dispose(); //結束寫入 74 bufferedImage.flush(); //結束buffered 75 ImageIO.write(bufferedImage, "png", new File("E:/img.png")); //將圖片寫入到指定路徑下 76 77 } 78 }
QRCode解析二維碼代碼如下:
1 import java.awt.image.BufferedImage; 2 import java.io.File; 3 import java.io.IOException; 4 5 import javax.imageio.ImageIO; 6 7 import jp.sourceforge.qrcode.QRCodeDecoder; 8 9 public class ReadQRCode { 10 11 public static void main(String[] args) throws IOException { 12 13 //圖片路徑 14 File file = new File("E:/img.png"); 15 //讀取圖片到緩沖區 16 BufferedImage bufferedImage = ImageIO.read(file); 17 //QRCode解碼器 18 QRCodeDecoder codeDecoder = new QRCodeDecoder(); 19 20 /** 21 *codeDecoder.decode(new MyQRCodeImage()) 22 *這里需要實現QRCodeImage接口,MyQRCodeImage.java實現接口類 23 */ 24 //通過解析二維碼獲得信息 25 String result = new String(codeDecoder.decode(new MyQRCodeImage(bufferedImage)), "utf-8"); 26 System.out.println(result); 27 } 28 }
MyQRCodeImage.java類實現QRCodeImage接口
1 import java.awt.image.BufferedImage; 2 3 import jp.sourceforge.qrcode.data.QRCodeImage; 4 5 public class MyQRCodeImage implements QRCodeImage{ 6 7 BufferedImage bufferedImage; 8 9 public MyQRCodeImage(BufferedImage bufferedImage) { 10 this.bufferedImage = bufferedImage; 11 } 12 13 //寬 14 @Override 15 public int getWidth() { 16 return bufferedImage.getWidth(); 17 } 18 19 //高 20 @Override 21 public int getHeight() { 22 return bufferedImage.getHeight(); 23 } 24 25 //顏色 26 @Override 27 public int getPixel(int i, int j) { 28 return bufferedImage.getRGB(i, j); 29 } 30 }
七、注意事項
jar包可放置在lib包下,還要設置此項目的builde path,選中項目,右擊,選擇Builde Path,點擊Configure Builde Path,在libraries下點擊Add Jars添加jar文件。
