• 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     }

      可以从二维码图片中解析出具体的内容。

  • 相关阅读:
    oracle 查询表空间
    oracle 创建表空间
    webservice SOA
    WCF初识
    win10远程桌面身份验证错误,要求的函数不受支持
    一台主机两台显示器实现方式学习
    实现Http Server学习
    lucene索引和查询文件系统存储
    java 大文件输入方式FileOutputStream
    tar
  • 原文地址:https://www.cnblogs.com/pcheng/p/7544553.html
Copyright © 2020-2023  润新知