Java基于zxing生成二維碼矩陣過程解析
這個(gè)例子需要使用google的開源項(xiàng)目zxing的核心jar包
core-3.2.0.jar
可以百度搜索下載jar文件,也可使用maven添加依賴
<dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.2.0</version> </dependency>
下面是將生成的二維碼矩陣寫入到j(luò)pg文件中。
* 生成二維碼圖片 * @param dir 存放的目錄 * @param fileName 文件名要以.jpg結(jié)尾 * @param content 這個(gè)內(nèi)容可以是文字或鏈接 */ public static void generateQRCode(String dir, String fileName, String content) { //生成二維碼的寬高 int size = 400; Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>(); // 指定糾錯(cuò)等級(jí) hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 指定編碼格式 hints.put(EncodeHintType.CHARACTER_SET, 'UTF-8'); // 指定二維碼的邊距,設(shè)置后無效,,設(shè)置糾錯(cuò)等級(jí)ErrorCorrectionLevel.H為高等級(jí)時(shí),無效 //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結(jié)尾 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(); } }
上面指定了糾錯(cuò)等級(jí)設(shè)置有四個(gè)值
/** L = ~7% correction */ L(0x01), /** M = ~15% correction */ M(0x00), /** Q = ~25% correction */ Q(0x03), /** H = ~30% correction */ H(0x02);
指定為L(zhǎng),M這兩個(gè)等級(jí)時(shí),二維碼大小會(huì)根據(jù)其存儲(chǔ)的數(shù)據(jù)量變化,即邊距肯能會(huì)很大,看下圖,
Q,H高等級(jí)時(shí),會(huì)按照標(biāo)準(zhǔn)格式顯示二維碼圖片。建議使用H等級(jí)。
這里生成的二維碼留的白色邊距有點(diǎn)多,想要適當(dāng)減小邊距,看下圖
如果不想邊距太大,我們可以將生成的二維碼圖片進(jìn)行剪切。新建立一個(gè)空的BitMatrix對(duì)象來放這個(gè)二維碼
margin為白色邊距的大小
private static BitMatrix updateBit(BitMatrix matrix, int margin) { int tempM = margin * 2; //left,top,width,height // 0 1 2 3 對(duì)應(yīng)的數(shù)組下標(biāo) //這里的width和height是指去除白色邊框后的真實(shí)的二維碼長(zhǎng)寬,而不是圖片長(zhǎng)寬。 int[] rec = matrix.getEnclosingRectangle(); // 獲取二維碼圖案的屬性 int resWidth = rec[2] + tempM;//真實(shí)寬度加左右邊距 int resHeight = rec[3] + tempM; BitMatrix resMatrix = new BitMatrix(resWidth, resHeight); // 按照自定義邊框生成新的BitMatrix resMatrix.clear(); //從上->下按列進(jìn)行值得復(fù)制,即一列一列的掃描到新的二維矩陣中 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; }
生成二維碼
這樣白色邊距就不會(huì)太大了,好看多了
后面還有將二維碼嵌入到海報(bào),或者其他活動(dòng)圖片上的方法,直接上代碼
將二維碼放置在圖片右下角的位置
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:QRCodezengmei.jpg')); System.out.println('創(chuàng)建成功'); } catch (IOException e) { e.printStackTrace(); } }
生成后的結(jié)果,圖片是本地隨便找了一張圖片
修改二維碼線條顏色,在二維碼中插入logo圖標(biāo)等方法
發(fā)現(xiàn)修改二維碼顏色之后,用微信,qq掃描二維碼很難被識(shí)別。這個(gè)很難受。這里說下怎么改。
修改原理就是,將內(nèi)容通過new MultiFormatWriter().encode()方法生成二維矩陣后,,
用一個(gè)新的BufferedImage對(duì)象作為容器給矩陣的兩個(gè)不同的值設(shè)置顏色,有值得為true,沒值false,即設(shè)置黑白兩種顏色
/** * * @param onColor 二維碼的顏色,即黑白二維碼的黑色 :0xFF000000 藍(lán)色 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>(); // 指定糾錯(cuò)等級(jí) 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
也就是設(shè)置顏色,然后返回BufferImage對(duì)象
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支持的圖像類型有三種,黑白顏色的默認(rèn)為BufferedImage.TYPE_BYTE_BINARY = 12,圖像不帶透明度alpha 最多是4bit的的圖像TYPE_INT_RGB 這個(gè)是不帶alpha的8bit圖像TYPE_INT_ARGB 這個(gè)帶alpha的8bit圖像java.awt.image.BufferedImage.BufferedImage(int width, int height, int imageType)
開源項(xiàng)目地址
https://github.com/zxing/zxing
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. HTML DOM setInterval和clearInterval方法案例詳解2. 告別AJAX實(shí)現(xiàn)無刷新提交表單3. CSS hack用法案例詳解4. WML語言的基本情況5. 使用純HTML的通用數(shù)據(jù)管理和服務(wù)6. 低版本IE正常運(yùn)行HTML5+CSS3網(wǎng)站的3種解決方案7. 使用css實(shí)現(xiàn)全兼容tooltip提示框8. css代碼優(yōu)化的12個(gè)技巧9. css進(jìn)階學(xué)習(xí) 選擇符10. CSS3實(shí)例分享之多重背景的實(shí)現(xiàn)(Multiple backgrounds)
