利用google Zxing 二维码生成与解析

本文转载自:https://blog.csdn.net/shenfuli/article/details/68923393

生成二维码的开源项目可谓是琳琅满目,SwetakeQRCode、BarCode4j、Zxing......  选择Zxing的原因可能是对 Google 公司的信赖和个人崇拜吧。  其实使用起来相当的简单。

我们考虑使用二维码解析的业务场景: 作为一个新闻资讯类的APP,需要通过爬虫技术手段抓取大量的新闻,但往往这些新闻中有大量的图片。通过该方案可以解决一部分内容。

1、通过maven方式直接引入相关的jar包

[html]  view plain  copy
  1. <!-- https://mvnrepository.com/artifact/com.google.zxing/core -->  
  2. <dependency>  
  3.   <groupId>com.google.zxing</groupId>  
  4.   <artifactId>core</artifactId>  
  5.   <version>3.3.0</version>  
  6. </dependency>  
  7. <!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->  
  8. <dependency>  
  9.   <groupId>com.google.zxing</groupId>  
  10.   <artifactId>javase</artifactId>  
  11.   <version>3.3.0</version>  
  12. </dependency>  

2、提供二维码生成和解析工具类

[html]  view plain  copy
  1. package com.forest.qr.utils;  
  2.   
  3. import com.google.zxing.*;  
  4. import com.google.zxing.client.j2se.BufferedImageLuminanceSource;  
  5. import com.google.zxing.common.BitMatrix;  
  6. import com.google.zxing.common.HybridBinarizer;  
  7. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;  
  8.   
  9. import javax.imageio.ImageIO;  
  10. import java.awt.*;  
  11. import java.awt.geom.RoundRectangle2D;  
  12. import java.awt.image.BufferedImage;  
  13. import java.io.File;  
  14. import java.io.OutputStream;  
  15. import java.util.Hashtable;  
  16. import java.util.Random;  
  17.   
  18. /**  
  19.  * 二维码工具类  
  20.  * Created by fuli.shen on 2017/3/31.  
  21.  */  
  22. public class QRCodeUtil {  
  23.   
  24.     private static final String CHARSET = "utf-8";  
  25.     private static final String FORMAT_NAME = "JPG";  
  26.     // 二维码尺寸  
  27.     private static final int QRCODE_SIZE = 300;  
  28.     // LOGO宽度  
  29.     private static final int WIDTH = 60;  
  30.     // LOGO高度  
  31.     private static final int HEIGHT = 60;  
  32.   
  33.     /**  
  34.      * 生成二维码的方法  
  35.      *  
  36.      * @param content      目标URL  
  37.      * @param imgPath      LOGO图片地址  
  38.      * @param needCompress 是否压缩LOGO  
  39.      * @return 二维码图片  
  40.      * @throws Exception  
  41.      */  
  42.     private static BufferedImage createImage(String content, String imgPath,  
  43.                                              boolean needCompress) throws Exception {  
  44.         Hashtable hints = new Hashtable();  
  45.         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);  
  46.         hints.put(EncodeHintType.CHARACTER_SET, CHARSET);  
  47.         hints.put(EncodeHintType.MARGIN, 1);  
  48.         BitMatrix bitMatrix = new MultiFormatWriter().encode(content,  
  49.                 BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);  
  50.         int width = bitMatrix.getWidth();  
  51.         int height = bitMatrix.getHeight();  
  52.         BufferedImage image = new BufferedImage(width, height,  
  53.                 BufferedImage.TYPE_INT_RGB);  
  54.         for (int x = 0; x < width; x++) {  
  55.             for (int y = 0; y < height; y++) {  
  56.                 image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000  
  57.                         : 0xFFFFFFFF);  
  58.             }  
  59.         }  
  60.         if (imgPath == null || "".equals(imgPath)) {  
  61.             return image;  
  62.         }  
  63.         // 插入图片  
  64.         QRCodeUtil.insertImage(image, imgPath, needCompress);  
  65.         return image;  
  66.     }  
  67.   
  68.   
  69.     /**  
  70.      * 插入LOGO  
  71.      *  
  72.      * @param source       二维码图片  
  73.      * @param imgPath      LOGO图片地址  
  74.      * @param needCompress 是否压缩  
  75.      * @throws Exception  
  76.      */  
  77.     private static void insertImage(BufferedImage source, String imgPath,  
  78.                                     boolean needCompress) throws Exception {  
  79.         File file = new File(imgPath);  
  80.         if (!file.exists()) {  
  81.             System.err.println("" + imgPath + "   该文件不存在!");  
  82.             return;  
  83.         }  
  84.         Image src = ImageIO.read(new File(imgPath));  
  85.         int width = src.getWidth(null);  
  86.         int height = src.getHeight(null);  
  87.         if (needCompress) { // 压缩LOGO  
  88.             if (width > WIDTH) {  
  89.                 width = WIDTH;  
  90.             }  
  91.             if (height > HEIGHT) {  
  92.                 height = HEIGHT;  
  93.             }  
  94.             Image image = src.getScaledInstance(width, height,  
  95.                     Image.SCALE_SMOOTH);  
  96.             BufferedImage tag = new BufferedImage(width, height,  
  97.                     BufferedImage.TYPE_INT_RGB);  
  98.             Graphics g = tag.getGraphics();  
  99.             g.drawImage(image, 0, 0, null); // 绘制缩小后的图  
  100.             g.dispose();  
  101.             src = image;  
  102.         }  
  103.         // 插入LOGO  
  104.         Graphics2D graph = source.createGraphics();  
  105.         int x = (QRCODE_SIZE - width) / 2;  
  106.         int y = (QRCODE_SIZE - height) / 2;  
  107.         graph.drawImage(src, x, y, width, height, null);  
  108.         Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);  
  109.         graph.setStroke(new BasicStroke(3f));  
  110.         graph.draw(shape);  
  111.         graph.dispose();  
  112.     }  
  113.   
  114.     /**  
  115.      * 生成二维码(内嵌LOGO)  
  116.      *  
  117.      * @param content      内容  
  118.      * @param imgPath      LOGO地址  
  119.      * @param destPath     存放目录  
  120.      * @param needCompress 是否压缩LOGO  
  121.      * @throws Exception  
  122.      */  
  123.     public static void encode(String content, String imgPath, String destPath,  
  124.                               boolean needCompress) throws Exception {  
  125.         BufferedImage image = QRCodeUtil.createImage(content, imgPath,  
  126.                 needCompress);  
  127.         mkdirs(destPath);  
  128.         String file = new Random().nextInt(99999999) + ".jpg";  
  129.         ImageIO.write(image, FORMAT_NAME, new File(destPath + "/" + file));  
  130.     }  
  131.   
  132.     /**  
  133.      * 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)  
  134.      *  
  135.      * @param destPath 存放目录  
  136.      */  
  137.     public static void mkdirs(String destPath) {  
  138.         File file = new File(destPath);  
  139.         if (!file.exists() && !file.isDirectory()) {  
  140.             file.mkdirs();  
  141.         }  
  142.     }  
  143.   
  144.     /**  
  145.      * 生成二维码(内嵌LOGO)  
  146.      *  
  147.      * @param content  内容  
  148.      * @param imgPath  LOGO地址  
  149.      * @param destPath 存储地址  
  150.      * @throws Exception  
  151.      */  
  152.     public static void encode(String content, String imgPath, String destPath)  
  153.             throws Exception {  
  154.         QRCodeUtil.encode(content, imgPath, destPath, false);  
  155.     }  
  156.   
  157.     /**  
  158.      * 生成二维码  
  159.      *  
  160.      * @param content      内容  
  161.      * @param destPath     存储地址  
  162.      * @param needCompress 是否压缩LOGO  
  163.      * @throws Exception  
  164.      */  
  165.     public static void encode(String content, String destPath,  
  166.                               boolean needCompress) throws Exception {  
  167.         QRCodeUtil.encode(content, null, destPath, needCompress);  
  168.     }  
  169.   
  170.     /**  
  171.      * 生成二维码  
  172.      *  
  173.      * @param content  内容  
  174.      * @param destPath 存储地址  
  175.      * @throws Exception  
  176.      */  
  177.     public static void encode(String content, String destPath) throws Exception {  
  178.         QRCodeUtil.encode(content, null, destPath, false);  
  179.     }  
  180.   
  181.     /**  
  182.      * 生成二维码(内嵌LOGO)  
  183.      *  
  184.      * @param content      内容  
  185.      * @param imgPath      LOGO地址  
  186.      * @param output       输出流  
  187.      * @param needCompress 是否压缩LOGO  
  188.      * @throws Exception  
  189.      */  
  190.     public static void encode(String content, String imgPath,  
  191.                               OutputStream output, boolean needCompress) throws Exception {  
  192.         BufferedImage image = QRCodeUtil.createImage(content, imgPath,  
  193.                 needCompress);  
  194.         ImageIO.write(image, FORMAT_NAME, output);  
  195.     }  
  196.   
  197.     /**  
  198.      * 生成二维码  
  199.      *  
  200.      * @param content 内容  
  201.      * @param output  输出流  
  202.      * @throws Exception  
  203.      */  
  204.     public static void encode(String content, OutputStream output)  
  205.             throws Exception {  
  206.         QRCodeUtil.encode(content, null, output, false);  
  207.     }  
  208.   
  209.     /**  
  210.      * 解析二维码  
  211.      *  
  212.      * @param file 二维码图片  
  213.      * @return  
  214.      * @throws Exception  
  215.      */  
  216.     public static String decode(File file) throws Exception {  
  217.         BufferedImage image;  
  218.         image = ImageIO.read(file);  
  219.         if (image == null) {  
  220.             return null;  
  221.         }  
  222.         BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(  
  223.                 image);  
  224.         BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));  
  225.         Result result;  
  226.         Hashtable hints = new Hashtable();  
  227.         hints.put(DecodeHintType.CHARACTER_SET, CHARSET);  
  228.         result = new MultiFormatReader().decode(bitmap, hints);  
  229.         String resultStr = result.getText();  
  230.         return resultStr;  
  231.     }  
  232.   
  233.     /**  
  234.      * 解析二维码  
  235.      *  
  236.      * @param path 二维码图片地址  
  237.      * @return  不是二维码的内容返回null,是二维码直接返回识别的结果  
  238.      * @throws Exception  
  239.      */  
  240.     public static String decode(String path) throws Exception {  
  241.         return QRCodeUtil.decode(new File(path));  
  242.     }  
  243.   
  244.     public static void main(String[] args)  {  
  245.   
  246.             // 生成二维码  
  247. //        String text = "https://www.baidu.com/";  
  248. //        String imagePath = System.getProperty("user.dir") + "/data/1.jpg";  
  249.             String destPath = System.getProperty("user.dir") + "/data/output/";  
  250. //        QRCodeUtil.encode(text, imagePath, destPath, true);  
  251.         //验证图片是否含有二维码  
  252.         String destPath1 = System.getProperty("user.dir") + "/data/3.jpg";  
  253.         try {  
  254.             String result = decode(destPath1);  
  255.             System.out.println(result);  
  256.         }catch (Exception e){  
  257.             e.printStackTrace();  
  258.             System.out.println(destPath1+"不是二维码");  
  259.         }  
  260.     }  
  261. }  

猜你喜欢

转载自blog.csdn.net/qq_40074764/article/details/80049290