zoukankan      html  css  js  c++  java
  • 使用google zxing生成二维码图片

    生成二维码工具类:

      1 import java.awt.geom.AffineTransform;
      2 import java.awt.image.AffineTransformOp;
      3 import java.awt.image.BufferedImage;
      4 import java.io.ByteArrayOutputStream;
      5 import java.io.IOException;
      6 import java.util.Hashtable;
      7 
      8 import javax.imageio.ImageIO;
      9 
     10 import org.apache.commons.codec.binary.Base64;
     11 
     12 import com.google.zxing.BarcodeFormat;
     13 import com.google.zxing.EncodeHintType;
     14 import com.google.zxing.common.BitMatrix;
     15 import com.google.zxing.qrcode.QRCodeWriter;
     16 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
     17 
     18 public class QRCodeUtil
     19 {
     20     
     21     private static final int BLACK = 0xFF000000;
     22     
     23     private static final int WHITE = 0xFFFFFFFF;
     24     
     25     /**
     26     * 生成二维码图片
     27     * @param content
     28     * @param width
     29     * @param height
     30     * @param hints
     31     * @return
     32     * @throws Exception
     33     */
     34     
     35     private static BufferedImage getQrCodeImage(String content, int width, int height, Hashtable hints) throws Exception
     36     {
     37         // 使用zxing生成二维码图片数据类BitMatrix
     38         QRCodeWriter writer = new QRCodeWriter();
     39         
     40         if (hints == null)
     41         {
     42             hints = new Hashtable();
     43             hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
     44         }
     45         //编码信息,生成二维码
     46         BitMatrix matrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
     47         
     48         // 修改默认生成的二维码白边
     49         BitMatrix newMatrix = updateFrameWidth(matrix, 0);
     50         
     51         // 缩放图片(因为裁剪了空白的边框)
     52         BufferedImage bi = toBufferedImage(newMatrix);
     53         
     54         // 计算x轴y轴缩放比例
     55         double sx = (double)width / bi.getWidth();
     56         double sy = (double)height / bi.getHeight();
     57         
     58         BufferedImage zoomImage = zoomInImage(bi, sx, sy);
     59         
     60         return zoomImage;
     61     }
     62     
     63     /**
     64     * 将google zxing生成的二维码数据结构BitMatrix的内容写入图片缓冲区BufferedImage
     65     * @param matrix
     66     * @return
     67     */
     68     
     69     public static BufferedImage toBufferedImage(BitMatrix matrix)
     70     {
     71         
     72         int width = matrix.getWidth();
     73         int height = matrix.getHeight();
     74         
     75         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
     76         
     77         for (int x = 0; x < width; x++)
     78         {
     79             for (int y = 0; y < height; y++)
     80             {
     81                 image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
     82             }
     83         }
     84         
     85         return image;
     86     }
     87     
     88     /**
     89      * 
     90      * 获取二维码字节流
     91      * @param content
     92      * @param width
     93      * @param height
     94      * @return
     95      * @throws Exception
     96      */
     97     
     98     public static byte[] getQrCodeImageBytes(String content, int width, int height, Hashtable hints) throws Exception
     99     {
    100         
    101         // 二维码输出质量,0:L(低), 1:M(中等), 2:Q, 3:H(高)
    102         int level = 3;
    103         
    104         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.forBits(3));
    105         hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
    106         
    107         // 生成二维码图片
    108         BufferedImage zoomImage = getQrCodeImage(content, width, height, hints);
    109         
    110         // 转为二进制字节
    111         ByteArrayOutputStream out = new ByteArrayOutputStream();
    112         
    113         if (!ImageIO.write(zoomImage, "png", out))
    114         {
    115             throw new IOException("Could not write an image of format png");
    116         }
    117         
    118         byte[] binaryData = out.toByteArray();
    119         
    120         return binaryData;
    121     }
    122     
    123     /**
    124     * 进行Base64编码
    125     * @param content
    126     * @param width
    127     * @param height
    128     * @param hints
    129     * @return
    130     * @throws Exception
    131     */
    132     
    133     public static String getQrCodeImageBase64String(String content, int width, int height, Hashtable hints) throws Exception
    134     {
    135         // 生成二维码图片的二进制字节
    136         byte[] binaryData = getQrCodeImageBytes(content, width, height, hints);
    137         
    138         // 将二进制字节进行Base64编码
    139         String ret = new String(Base64.encodeBase64(binaryData), "UTF-8");
    140         
    141         return ret;
    142     }
    143     
    144     /**
    145     * 指定缩放比例,进行图片缩放
    146     * @param originalImage
    147     * @param sx
    148     * @param sy
    149     * @return
    150     */
    151     public static BufferedImage zoomInImage(BufferedImage originalImage, double sx, double sy)
    152     {
    153         AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(sx, sy), null);
    154         BufferedImage newImage = op.filter(originalImage, null);
    155         
    156         return newImage;
    157     }
    158     
    159     /**
    160     * 自定义修改二维码的白边宽度
    161     * @param matrix
    162     * @param margin
    163     * @return
    164     */
    165     public static BitMatrix updateFrameWidth(BitMatrix matrix, int margin)
    166     {
    167         int tempM = margin * 2;
    168         
    169         // 二维码的实际尺寸
    170         int[] whitesTopLeft = getFrameWidthOfTopLeft(matrix);
    171         int[] whitesBottomRight = getFrameWidthOfBottomRight(matrix);
    172         
    173         int whiteWidth = whitesTopLeft[0] + whitesBottomRight[0];
    174         int whiteHeight = whitesTopLeft[1] + whitesBottomRight[1];
    175         
    176         int height = matrix.getHeight() - whiteWidth + tempM;
    177         int width = matrix.getWidth() - whiteHeight + tempM;
    178         
    179         // 按照自定义边框生成新的BitMatrix
    180         BitMatrix resMatrix = new BitMatrix(width, height);
    181         resMatrix.clear();
    182         
    183         // 循环,将二维码图案绘制到新的bitMatrix中
    184         for (int i = margin; i < width - margin; i++)
    185         {
    186             for (int j = margin; j < height - margin; j++)
    187             {
    188                 if (matrix.get(i - margin + whitesTopLeft[0], j - margin + whitesTopLeft[1]))
    189                 {
    190                     // 新的二维码
    191                     resMatrix.set(i, j);
    192                 }
    193             }
    194         }
    195         
    196         return resMatrix;
    197     }
    198     
    199     /**
    200     * 二维码左上角白边的尺寸
    201     * @param matrix
    202     * @return
    203     */
    204     private static int[] getFrameWidthOfTopLeft(BitMatrix matrix)
    205     {
    206         // 二维码的尺寸
    207         int height = matrix.getHeight();
    208         int width = matrix.getWidth();
    209         
    210         // 循环,遇到第一个黑点,就返回
    211         for (int i = 0; i < width; i++)
    212         {
    213             for (int j = 0; j < height; j++)
    214             {
    215                 if (matrix.get(i, j) == true)
    216                 {
    217                     int[] ret = {i, j};
    218                     return ret;
    219                 }
    220             }
    221         }
    222         
    223         int[] ret = {0, 0};
    224         return ret;
    225     }
    226     
    227     /**
    228     * 二维码右下角白边的尺寸
    229     * @param matrix
    230     * @return
    231     */
    232     private static int[] getFrameWidthOfBottomRight(BitMatrix matrix)
    233     {
    234         // 二维码的尺寸
    235         int height = matrix.getHeight();
    236         int width = matrix.getWidth();
    237         
    238         // 备注:不能直接查找右下角的第一个黑点,而必须分别查找右上角、左下角的第一个黑点,然后返回右下角坐标
    239         int right = -1;
    240         
    241         // 从右上角开始循环,遇到第一个黑点,就得到右边空白宽度
    242         for (int i = width; i > 0; i--)
    243         {
    244             for (int j = 0; j < height; j++)
    245             {
    246                 if (matrix.get(i - 1, j) == true)
    247                 {
    248                     right = width - i;
    249                     break;
    250                 }
    251             }
    252             
    253             if (right >= 0)
    254             {
    255                 break;
    256             }
    257         }
    258         
    259         // 从左下角开始循环,遇到第一个黑点,就得到下边空白宽度,返回
    260         for (int i = 0; i < width; i++)
    261         {
    262             for (int j = height; j > 0; j--)
    263             {
    264                 if (matrix.get(i, j - 1) == true)
    265                 {
    266                     int[] ret = {right, height - j};
    267                     return ret;
    268                 }
    269             }
    270         }
    271         
    272         int[] ret = {0, 0};
    273         return ret;
    274     }
    275     
    276 }

    作者:鲁班快跑

    出处:https://www.cnblogs.com/zhusf/p/15503229.html

    版权:本文版权归作者和博客园共有

    转载:您可以随意转载、摘录,但请在文章内注明作者和原文链接。

  • 相关阅读:
    设计模式
    LintCode 数组(一)
    LintCode 字符串(二)
    LintCode 字符串(一)
    Java 多线程---volatile, ThreadLocal
    HTTP之缓存首部
    HTTP之首部
    HTTP之状态码
    web安全之XSS和CSRF
    web安全之同源策略
  • 原文地址:https://www.cnblogs.com/zhusf/p/15503229.html
Copyright © 2011-2022 走看看