Java基於zxing生成二維碼矩陣過程解析
阿新 • • 發佈:2020-09-28
這個例子需要使用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,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("建立成功"); } 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這兩個等級時,二維碼大小會根據其儲存的資料量變化,即邊距肯能會很大,看下圖,
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 對應的陣列下標 //這裡的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++) { // 迴圈,將二維碼圖案繪製到新的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,new FileOutputStream("D:\\QRCode\\zengmei.jpg")); System.out.println("建立成功"); } catch (IOException e) { e.printStackTrace(); } }
生成後的結果,圖片是本地隨便找了一張圖片
修改二維碼線條顏色,在二維碼中插入logo圖示等方法
發現修改二維碼顏色之後,用微信,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,ErrorCorrectionLevel.Q); // 指定編碼格式 hints.put(EncodeHintType.CHARACTER_SET,"UTF-8"); try { BitMatrix bitMatrix = new MultiFormatWriter().encode(content,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 imageType)
開源專案地址
https://github.com/zxing/zxing
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。