Java基于zxing生成二維碼矩陣過程解析
這個例子需要使用google的開源項目zxing的核心jar包
core-3.2.0.jar
可以百度搜索下載jar文件,也可使用maven添加依賴
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.2.0</version>
</dependency>
下面是將生成的二維碼矩陣寫入到jpg文件中。
* 生成二維碼圖片
* @param dir 存放的目錄
* @param fileName 文件名要以.jpg結尾
* @param content 這個內容可以是文字或鏈接
*/
public static void generateQRCode(String dir, String fileName, String content) {
//生成二維碼的寬高
int size = 400;
Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
// 指定糾錯等級
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
// 指定編碼格式
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
// 指定二維碼的邊距,設置后無效,,設置糾錯等級ErrorCorrectionLevel.H為高等級時,無效 //hints.put(EncodeHintType.MARGIN, 1);
try {
//encode(String contents, BarcodeFormat format, int width, int height, Map<EncodeHintType, ?> hints)
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
//bitMatrix = updateBit(bitMatrix, 20);
File file1 = new File(dir);
if (!file1.exists()) {
file1.mkdirs();
}
//將生成的矩陣像素寫入到指定文件中,這里是以jpg結尾
MatrixToImageWriter.writeToStream(bitMatrix, "jpg", new FileOutputStream(dir + "/" + fileName));
System.out.println("創(chuàng)建成功");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (WriterException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
上面指定了糾錯等級設置有四個值
/** L = ~7% correction */ L(0x01), /** M = ~15% correction */ M(0x00), /** Q = ~25% correction */ Q(0x03), /** H = ~30% correction */ H(0x02);
指定為L,M這兩個等級時,二維碼大小會根據(jù)其存儲的數(shù)據(jù)量變化,即邊距肯能會很大,看下圖,
Q,H高等級時,會按照標準格式顯示二維碼圖片。建議使用H等級。
這里生成的二維碼留的白色邊距有點多,想要適當減小邊距,看下圖

如果不想邊距太大,我們可以將生成的二維碼圖片進行剪切。新建立一個空的BitMatrix對象來放這個二維碼
margin為白色邊距的大小
private static BitMatrix updateBit(BitMatrix matrix, int margin) {
int tempM = margin * 2;
//left,top,width,height
// 0 1 2 3 對應的數(shù)組下標
//這里的width和height是指去除白色邊框后的真實的二維碼長寬,而不是圖片長寬。
int[] rec = matrix.getEnclosingRectangle(); // 獲取二維碼圖案的屬性
int resWidth = rec[2] + tempM;//真實寬度加左右邊距
int resHeight = rec[3] + tempM;
BitMatrix resMatrix = new BitMatrix(resWidth, resHeight); // 按照自定義邊框生成新的BitMatrix
resMatrix.clear();
//從上->下按列進行值得復制,即一列一列的掃描到新的二維矩陣中
for (int i = margin; i < resWidth - margin; i++) { // 循環(huán),將二維碼圖案繪制到新的bitMatrix中
for (int j = margin; j < resHeight - margin; j++) {
//margin + rec[0]
if (matrix.get(i - margin + rec[0], j - margin + rec[1])) {
resMatrix.set(i, j);
}
}
}
return resMatrix;
}
生成二維碼

這樣白色邊距就不會太大了,好看多了
后面還有將二維碼嵌入到海報,或者其他活動圖片上的方法,直接上代碼
將二維碼放置在圖片右下角的位置
public void insertQRCode(BufferedImage zxingImage, String backgroundPath) {
InputStream dest = null;
try {
dest = new FileInputStream(backgroundPath);
BufferedImage image = ImageIO.read(dest);
Graphics g = image.getGraphics();
int leftMargin = image.getWidth() - zxingImage.getWidth() - 10;
int topMargin = image.getHeight() - zxingImage.getHeight() - 10;
g.drawImage(zxingImage, leftMargin, topMargin, zxingImage.getWidth(), zxingImage.getHeight(), null);
ImageIO.write(image, "jpg", new FileOutputStream("D:\\QRCode\\zengmei.jpg"));
System.out.println("創(chuàng)建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
生成后的結果,圖片是本地隨便找了一張圖片

修改二維碼線條顏色,在二維碼中插入logo圖標等方法
發(fā)現(xiàn)修改二維碼顏色之后,用微信,qq掃描二維碼很難被識別。這個很難受。這里說下怎么改。
修改原理就是,將內容通過new MultiFormatWriter().encode()方法生成二維矩陣后,,
用一個新的BufferedImage對象作為容器給矩陣的兩個不同的值設置顏色,有值得為true,沒值false,即設置黑白兩種顏色
/**
*
* @param onColor 二維碼的顏色,即黑白二維碼的黑色 :0xFF000000 藍色 0xFF000055
* @param offColor 二維碼的背景色 如白色:0xFFFFFFFF
*/
public static void generateOtherQRCode(int onColor, int offColor) {
String content = "小姐姐最棒啦^_^";
int size = 200;
Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
// 指定糾錯等級
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
// 指定編碼格式
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size, hints);
BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix,
new MatrixToImageConfig(onColor, offColor));
ImageIO.write(image, "png", new FileOutputStream("D:/QRCode/beautiful.png"));
System.out.println("操作成功");
} catch (IOException e) {
e.printStackTrace();
} catch (WriterException e) {
e.printStackTrace();
}
}
重要方法是:MatrixToImageWriter.toBufferedImage
也就是設置顏色,然后返回BufferImage對象
public static BufferedImage toBufferedImage(BitMatrix matrix, MatrixToImageConfig config) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, config.getBufferedImageColorModel());
int onColor = config.getPixelOnColor();
int offColor = config.getPixelOffColor();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? onColor : offColor);
}
}
return image;
}
//imageType , zxing支持的圖像類型有三種,黑白顏色的默認為BufferedImage.TYPE_BYTE_BINARY = 12,圖像不帶透明度alpha 最多是4bit的的圖像TYPE_INT_RGB 這個是不帶alpha的8bit圖像TYPE_INT_ARGB 這個帶alpha的8bit圖像 java.awt.image.BufferedImage.BufferedImage(int width, int height, int imageType)
開源項目地址
https://github.com/zxing/zxing
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Java數(shù)據(jù)結構與算法之循環(huán)隊列的實現(xiàn)
循環(huán)隊列 (Circular Queue) 是一種特殊的隊列。循環(huán)隊列解決了隊列出隊時需要將所有數(shù)據(jù)前移一位的問題。本文將帶大家詳細了解循環(huán)隊列如何實現(xiàn),需要的朋友可以參考一下2021-12-12
解決RestTemplate 的getForEntity調用接口亂碼的問題
這篇文章主要介紹了解決RestTemplate 的getForEntity調用接口亂碼的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
SpringBoot實現(xiàn)自定義Redis的連接的流程步驟
Spring Boot 自定義 Redis 主要是指在基于 Spring Boot 的應用程序中,當你需要更深入地控制或擴展對 Redis 數(shù)據(jù)庫的操作,而不是僅僅依賴 Spring Data Redis 的默認配置,本文給大家介紹了SpringBoot實現(xiàn)自定義Redis的連接的流程步驟,需要的朋友可以參考下2024-09-09
SpringBoot?web靜態(tài)資源映射實現(xiàn)步驟詳解
在springBoot中的靜態(tài)資源的映射是通過SpringMVC中的resourceHttpRequestHandler來進行實現(xiàn)的。在該請求映射器中默認規(guī)定了,SpringBoot會將classPath或者ServletContext下的/static?(/public、/resources?或?/META-INF/resources)目錄中,存放靜態(tài)資源2022-09-09
SpringBoot整合Dubbo+Zookeeper實現(xiàn)RPC調用
這篇文章主要給大家介紹了Spring Boot整合Dubbo+Zookeeper實現(xiàn)RPC調用的步驟詳解,文中有詳細的代碼示例,對我們的學習或工作有一定的幫助,需要的朋友可以參考下2023-07-07

