JAVA中生成、解析二維碼圖片的方法


  JAVA中生成、解析二維碼的方法並不復雜,使用google的zxing包就可以實現。下面的方法包含了生成二維碼、在中間附加logo、添加文字功能,並有解析二維碼的方法。

 

一、下載zxing的架包,並導入項目中,如下:

最主要的包都在com.google.zxing.core下。如果是maven項目,maven依賴如下:

1 <dependency>
2   <groupId>com.google.zxing</groupId>
3   <artifactId>core</artifactId>
4   <version>3.3.0</version>
5 </dependency>

 

二、二維碼生成,附上代碼例子,如下:

  1 public class TestQRcode {
  2     
  3     private static final int BLACK = 0xFF000000;
  4     private static final int WHITE = 0xFFFFFFFF;
  5     private static final int margin = 0;
  6     private static final int LogoPart = 4;
  7     
  8     /**
  9      * 生成二維碼矩陣信息
 10      * @param content 二維碼圖片內容
 11      * @param width 二維碼圖片寬度
 12      * @param height 二維碼圖片高度
 13      */
 14     public static BitMatrix setBitMatrix(String content, int width, int height){
 15         Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
 16         hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 指定編碼方式,防止中文亂碼
 17         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 指定糾錯等級
 18         hints.put(EncodeHintType.MARGIN, margin); // 指定二維碼四周白色區域大小
 19         BitMatrix bitMatrix = null;
 20         try {
 21             bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
 22         } catch (WriterException e) {
 23             e.printStackTrace();
 24         }
 25         return bitMatrix;
 26     }
 27     
 28     /** 
 29      * 將二維碼圖片輸出
 30      * @param matrix 二維碼矩陣信息
 31      * @param format 圖片格式
 32      * @param outStream 輸出流
 33      * @param logoPath logo圖片路徑
 34      */  
 35     public static void writeToFile(BitMatrix matrix, String format, OutputStream outStream, String logoPath) throws IOException {
 36         BufferedImage image = toBufferedImage(matrix);
 37         // 加入LOGO水印效果
 38         if (StringUtils.isNotBlank(logoPath)) {
 39             image = addLogo(image, logoPath);
 40         }
 41         ImageIO.write(image, format, outStream);
 42     }
 43     
 44     /**
 45      * 生成二維碼圖片
 46      * @param matrix 二維碼矩陣信息
 47      */
 48     public static BufferedImage toBufferedImage(BitMatrix matrix) {
 49         int width = matrix.getWidth();
 50         int height = matrix.getHeight();
 51         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
 52         for (int x = 0; x < width; x++) {
 53             for (int y = 0; y < height; y++) {
 54                 image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
 55             }
 56         }
 57         return image;
 58     }
 59     
 60     /**
 61      * 在二維碼圖片中添加logo圖片
 62      * @param image 二維碼圖片
 63      * @param logoPath logo圖片路徑
 64      */
 65     public static BufferedImage addLogo(BufferedImage image, String logoPath) throws IOException {
 66         Graphics2D g = image.createGraphics();
 67         BufferedImage logoImage = ImageIO.read(new File(logoPath));
 68         // 計算logo圖片大小,可適應長方形圖片,根據較短邊生成正方形
 69         int width = image.getWidth() < image.getHeight() ? image.getWidth() / LogoPart : image.getHeight() / LogoPart;
 70         int height = width;
 71         // 計算logo圖片放置位置
 72         int x = (image.getWidth() - width) / 2;
 73         int y = (image.getHeight() - height) / 2;
 74         // 在二維碼圖片上繪制logo圖片
 75         g.drawImage(logoImage, x, y, width, height, null);
 76         // 繪制logo邊框,可選
 77 //        g.drawRoundRect(x, y, logoImage.getWidth(), logoImage.getHeight(), 10, 10);
 78         g.setStroke(new BasicStroke(2)); // 畫筆粗細
 79         g.setColor(Color.WHITE); // 邊框顏色
 80         g.drawRect(x, y, width, height); // 矩形邊框
 81         logoImage.flush();
 82         g.dispose();
 83         return image;
 84     }
 85     
 86     /**
 87      * 為圖片添加文字
 88      * @param pressText 文字
 89      * @param newImage 帶文字的圖片
 90      * @param targetImage 需要添加文字的圖片
 91      * @param fontStyle 字體風格
 92      * @param color 字體顏色
 93      * @param fontSize 字體大小
 94      * @param width 圖片寬度
 95      * @param height 圖片高度
 96      */
 97     public static void pressText(String pressText, String newImage, String targetImage, int fontStyle, Color color, int fontSize, int width, int height) {
 98         // 計算文字開始的位置
 99         // x開始的位置:(圖片寬度-字體大小*字的個數)/2
100         int startX = (width-(fontSize*pressText.length()))/2;
101         // y開始的位置:圖片高度-(圖片高度-圖片寬度)/2
102         int startY = height-(height-width)/2 + fontSize;
103         try {
104             File file = new File(targetImage);
105             BufferedImage src = ImageIO.read(file);
106             int imageW = src.getWidth(null);
107             int imageH = src.getHeight(null);
108             BufferedImage image = new BufferedImage(imageW, imageH, BufferedImage.TYPE_INT_RGB);
109             Graphics g = image.createGraphics();
110             g.drawImage(src, 0, 0, imageW, imageH, null);
111             g.setColor(color);
112             g.setFont(new Font(null, fontStyle, fontSize));
113             g.drawString(pressText, startX, startY);
114             g.dispose();
115             FileOutputStream out = new FileOutputStream(newImage);
116             ImageIO.write(image, "png", out);
117             out.close();
118         } catch (Exception e) {
119             e.printStackTrace();
120         }
121     }
122     
123     public static void main(String[] args) {
124         String content = "http://www.baidu.com";
125         String logoPath = "C:/logo.png";
126         String format = "jpg";
127         int width = 180;
128         int height = 220;
129         BitMatrix bitMatrix = setBitMatrix(content, width, height);
130         // 可通過輸出流輸出到頁面,也可直接保存到文件
131         OutputStream outStream = null;
132         String path = "c:/qr"+new Date().getTime()+".png";
133         try {
134             outStream = new FileOutputStream(new File(path));        
135             writeToFile(bitMatrix, format, outStream, logoPath);
136             outStream.close();
137         } catch (Exception e) {
138             e.printStackTrace();
139         }
140         // 添加文字效果
141         int fontSize = 12; // 字體大小
142         int fontStyle = 1; // 字體風格
143         String text = "測試二維碼";
144         String withTextPath = "c:/text"+new Date().getTime()+".png";
145         pressText(text, withTextPath, path, fontStyle, Color.BLUE, fontSize, width, height);
146     }
147 }

 

三、生成效果如下:

  代碼注釋比較詳細,就不多解釋啦,大家可以根據自己的需求進行調整。

PS:

1、如果想生成帶文字的二維碼,記得要用長方形圖片,為文字預留空間。

2、要生成帶logo的二維碼要注意遮擋率的問題,setBitMatrix()方法中ErrorCorrectionLevel.H這個糾錯等級參數決定了二維碼可被遮擋率。對應如下:

L水平 7%的字碼可被修正
M水平 15%的字碼可被修正
Q水平 25%的字碼可被修正
H水平 30%的字碼可被修正

 

 

 

 

 

四、二維碼解析,附上代碼例子,如下:

 1     /**
 2      * 解析二維碼圖片
 3      * @param filePath 圖片路徑
 4      */
 5     public static String decodeQR(String filePath) {
 6         if ("".equalsIgnoreCase(filePath) && filePath.length() == 0) {
 7             return "二維碼圖片不存在!";
 8         }
 9         String content = "";
10         EnumMap<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
11         hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); // 指定編碼方式,防止中文亂碼
12         try {
13             BufferedImage image = ImageIO.read(new FileInputStream(filePath));
14             LuminanceSource source = new BufferedImageLuminanceSource(image);
15             Binarizer binarizer = new HybridBinarizer(source);
16             BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
17             MultiFormatReader reader = new MultiFormatReader();
18             Result result = reader.decode(binaryBitmap, hints);
19             content = result.getText();
20         } catch (Exception e) {
21             e.printStackTrace();
22         }
23         return content;
24     }

  可以從二維碼圖片中解析出具體的內容。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM