編碼前的準備:
goole生成二維碼的依賴:
<!--google生成二維碼的依賴-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.0.0</version>
</dependency>
使用阿里的fastjson jar包:
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
(使用fastjson,可以方便地完成 json對象和 json字符串的相互轉化。)
思路:
使用Java生成一個二維碼,主要依賴的是google的zxing類庫。他底層實現了二維碼生成的策略,我們做的僅僅是調用它的api,幫助我們生成二維碼對象,最終這個二維碼對象被我們用文件流來寫入到磁盤。
生成一個二維碼,需要哪些東西呢?
我們生活中最常見的二維碼,它們其實都是用二維碼的形式去刻畫一個字符串。所有的請求,也就是url,它們也全是字符串。
那麼字符串必然是生成二維碼的一個必要條件。此外,我們還需要二維碼的寬度和高度,二維碼的字符集以及二維碼的顏色,外邊距(留白),糾錯等級等等,都可以自行設計。
zxing包中的MultiFormatWriter
類是我們生成二維碼的核心工具類。我們主要使用它的encode
方法,用來將要封裝的字符串內容轉變爲二維碼對象。
但是要注意MultiFormatWriter功能很強大,他不僅可以幫我們生成二維碼,還可以生成條形碼,其他各種各種的碼。那麼我們就得提供一個參數來告訴MultiFormatWriter我們要生成的碼的類型是二維碼,即QRCode。
還有就是,爲了讓封裝的字符串支持中文顯示,我們設置字符集,設置萬國碼即“UTF-8”。設置編碼同樣是採用傳參的方式。
以上都是生成一個二維碼的最基本條件。即:
1、字符串(內容content)
2、碼的格式(ORCODE)
3、寬度(width)
4、高度(height)
5、字符集(它作爲參數要封裝在Map集合裏)
有了以上4個條件,我們完全可以生成二維碼了。
附:現實中的二維碼,比如微信支付中的二維碼,它使用的字符串是json格式的字符串。
爲了模擬現實場景,我們才需要導入fastjson來幫我們快速生成json格式的字符串。(實際上使用任何字符串都是可以的),也就是說,僅僅生成二維碼,fastjson不是必須的。
好,一通廢話講完,來看看代碼,一會再來慢慢寫廢話。
Java實現:
public class ORCode {
@Test
public void generateORCode() throws WriterException, IOException {
//生成一個二維碼
//定義一個json格式的字符串,使用fastjson(它能完成json字符串和json對象的相互轉化)
//1.創建一個jsonObject對象
JSONObject jsonObject = new JSONObject();
//2.給jsonObject對象中存放數據
jsonObject.put("username","root");
jsonObject.put("password","123456");
jsonObject.put("sex","男");
jsonObject.put("address","北京市");
//json對象轉換爲json格式的字符串
String contents = jsonObject.toString();
//System.out.println(jsonString);
//二維碼的寬高
int width = 200;
int height = 200;
//創建一個map集合,存放字符集
Map<EncodeHintType,Object> hints = new HashMap<EncodeHintType,Object>();
hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
//定義一個矩陣對象,生成二維碼的關鍵代碼:實例化一個矩陣對象
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE,width,height,hints);
//圖片的路徑
String filePath = "E://";
//圖片的名稱
String fileName = "QRCode1.jpg";
//創建一個路徑對象
Path path = FileSystems.getDefault().getPath(filePath+fileName);
//將矩陣對象轉化爲圖片
MatrixToImageWriter.writeToPath(bitMatrix,"jpg",path);
System.err.println("二維碼生成完畢");
}
}
生成的結果:
瞭解一下
看到了嗎,代碼很簡單,關鍵代碼就一行:
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE,width,height,hints);
然後我們來了解一些關於二維碼的小常識:
-
我們日常所使用的二維碼,也就是時下最流行的二維碼,它叫做
ORCode
,是日本發明的。 -
而早期的二維碼,有一個叫做
PDF417
,它是美國發明的,目前也有人在使用。 -
而中國發明的二維碼,叫做
漢信碼
。 -
DM碼,也是美國發明的。
4種二維碼對比:
另外,二維碼是分糾錯等級的。也是說我這個二維碼丟失了一部分,或者說掃描的不全,有多大程度上保證信息完整而不會出錯呢?
糾錯等級分4級,糾錯等級越高,糾錯能力越強,分的像素點就越多,二維碼看起來更密集,丟失部分後保證完整性的可能性越大。
糾錯等級 | 含義 | 最大可丟失 |
---|---|---|
L | Low | 7% |
M | Middle | 15% |
Q | Quartered | 25% |
H | High | 30% |
還有,我們可以自定義二維碼一些屬性,來使得我們的二維碼儘可能更滿足實際需求。
比如,設置二維碼的margin(外邊距),維持一定的留白。
還要設置一下糾錯等級。
這些信息,我們都同編碼格式一樣,放在Map集合中存儲。
我們重新寫一份代碼來生成二維碼:
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class GenerateORCode {
public static void main(String[] args) throws WriterException, IOException {
MultiFormatWriter mfw = new MultiFormatWriter();
//mfw.encode()
String content = "今天下雨了,很冷";
BarcodeFormat codeType = BarcodeFormat.QR_CODE;
int width = 666;
int height = 666;
Map<EncodeHintType,Object> map = new HashMap();//用來存儲二維碼的其他信息,儘管這些信息可能並不是生成二維碼必要條件
map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//設置糾錯等級爲M
map.put(EncodeHintType.MARGIN,2);//設置外邊距爲2
//還可以存放其他很多信息·····
//生成二維碼對象
BitMatrix bitMatrix = mfw.encode(content, codeType, width, height, map);
//利用java.awt.image包下的BufferedImage,利用它設置生成圖片的每個像素的顏色
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
int Green = Color.GREEN.getRGB();
int Yellow = Color.YELLOW.getRGB();
for (int x = 0;x<width;x++){
for (int y = 0;y<height;y++){
image.setRGB(x,y,bitMatrix.get(x,y)?Green:Yellow);
}
}
//需要將上面的image寫入文件
File file = new File("E://test//QRcode.jpg");
ImageIO.write(image,"jpg",file);
System.out.println("二維碼生成完畢");
}
}
效果:
附:關於 fastjson的一些說明
fastjson.jar是阿里巴巴開發的一款專門用於Java開發的包,可以方便的實現json對象與JavaBean對象的轉換,實現JavaBean對象與json字符串的轉換,實現json對象與json字符串的轉換。除了這個fastjson以外,還有Google開發的Gson包,其他形式的如net.sf.json包,都可以實現json的轉換。方法名稱不同而已,最後的實現結果都是一樣的。
1、javaBean 轉化爲 jsonString
String str1=JSON.toJSONString(student);
2、jsonString 轉化爲 javaBean
Student stu1=JSON.parseObject(str1,Student.class);
3、javaBean 轉化爲 jsonObject
JSONObject jsonObject1=(JSONObject)JSON.toJSON(student);
4、jsonObject 轉化爲 javaBean
Student student2=JSON.toJavaObject(jsonObject1, Student.class);
5、javaBean 轉化爲 jsonArray
JSONArray jsonArrays=(JSONArray)JSON.toJSON(stulist);
6、jsonArry 轉化爲 javalist
for(int i=0;i<jsonArrays.size();i++){
Student student3=JSON.toJavaObject(jsonArrays.getJSONObject(i), Student.class);
myList.add(student3);
}
7、jsonObject 轉化爲 jsonString
String str4=JSON.toJSONString(jsonObject1);
8、jsonString 轉化爲 jsonObject
JSONObject jso1=JSON.parseObject(str1);
9、jsonString 轉化爲 jsonArray
JSONArray jArray=JSON.parseArray(JSON.toJSONString(stulist));