• java实现二维码的生成和解析:QRCode、zxing 两种方式


    第一种:QRCode.jar,使用QRCode生成和解析二维码

    1.导入jar包

     2.代码

    (1)QRCodeUtil .java

      1 import com.swetake.util.Qrcode;
      2 import jp.sourceforge.qrcode.QRCodeDecoder;
      3 
      4 import javax.imageio.ImageIO;
      5 import java.awt.*;
      6 import java.awt.image.BufferedImage;
      7 import java.io.File;
      8 
      9 public class QRCodeUtil {
     10     /**
     11      *加密:  文字信息 ->二维码.png
     12      * @param content 文字信息
     13      * @param imgPath 二维码路径
     14      * @param imgType 二维码类型:png
     15      * @param size    二维码尺寸
     16      * @throws Exception
     17      */
     18     public void encoderQRCode(String content,String imgPath,String imgType,int size)  throws Exception{
     19         //BufferedImage :内存中的一张图片
     20         BufferedImage bufImg =   qRcodeCommon(content,imgType,size);
     21 
     22         File file = new File(imgPath);// "src/二维码.png" --> 二维码.png
     23 
     24         //生成图片
     25         ImageIO.write(bufImg, imgType, file);
     26     }
     27 
     28     /**
     29      *产生一个二维码的BufferedImage
     30      * @param content 二维码隐藏信息
     31      * @param imgType 图片格式
     32      * @param size    图片大小
     33      * @return
     34      */
     35     private BufferedImage qRcodeCommon(String content, String imgType, int size) throws Exception {
     36         BufferedImage bufImg =null;
     37         //Qrcode对象:字符串->boolean[][]
     38         Qrcode qrCodeHandler = new Qrcode();
     39         //设置二维码的排错率:7% L<M<Q<H30%  :排错率越高,可存储的信息越少;但是对二维码清晰对要求越小
     40         qrCodeHandler.setQrcodeErrorCorrect('M');
     41         //可存放的信息类型:N:数字、  A:数字+A-Z  B:所有
     42         qrCodeHandler.setQrcodeEncodeMode('B');
     43         //尺寸:取值范围:1-40
     44         qrCodeHandler.setQrcodeVersion(size);
     45 
     46         //"Hello world" -> byte[]"Hello world" -->boolean[][]
     47         byte[] contentBytes = content.getBytes("UTF-8");
     48         boolean[][] codeOut = qrCodeHandler.calQrcode(contentBytes);
     49 
     50         int imgSize =  67 + 12*(size -1) ;
     51 
     52         //BufferedImage:内存中的图片
     53         bufImg = new BufferedImage(imgSize,imgSize,BufferedImage.TYPE_INT_RGB );//red green blue
     54 
     55         //创建一个画板
     56         Graphics2D gs = bufImg.createGraphics();
     57         gs.setBackground(Color.WHITE);//将画板的背景色设置为白色
     58         gs.clearRect( 0,0, imgSize,imgSize); //初始化
     59         gs.setColor(Color.BLACK);//设置 画板上 图像的颜色(二维码的颜色)
     60 
     61         int pixoff = 2 ;
     62 
     63         for(int j=0;j<codeOut.length;j++) {
     64             for(int i=0;i<codeOut.length;i++) {
     65                 if(codeOut[j][i]) {
     66                     gs.fillRect(j*3+pixoff , i*3+pixoff, 3, 3);
     67                 }
     68             }
     69         }
     70         //增加LOGO
     71         //将硬盘中的src/logo.png  加载为一个Image对象
     72         Image logo =  ImageIO.read(new File("/src/logo.png")  ) ;
     73         int maxHeight = bufImg.getHeight();
     74         int maxWdith = bufImg.getWidth();
     75 
     76         //在已生成的二维码上 画logo
     77         gs.drawImage(logo,imgSize/5*2,imgSize/5*2, maxWdith/5,maxHeight/5 ,null) ;
     78 
     79         gs.dispose(); //释放空间
     80         bufImg.flush(); //清理
     81         return bufImg ;
     82     }
     83 
     84     //解密:  二维码(图片路径) -> 文字信息
     85     public String decoderQRCode(String imgPath) throws Exception{
     86 
     87         //BufferedImage内存中的图片  :硬盘中的imgPath图片 ->内存BufferedImage
     88         BufferedImage bufImg =  ImageIO.read( new File(imgPath) ) ;
     89         //解密
     90         QRCodeDecoder decoder = new QRCodeDecoder() ;
     91 
     92         TwoDimensionCodeImage tdcImage = new TwoDimensionCodeImage(bufImg);
     93         byte[] bs = decoder.decode(tdcImage) ;    //bufImg
     94         //byte[] -->String
     95         String content    = new String(bs,"UTF-8");
     96         return content;
     97     }
     98 
     99 
    100 }

     (2)TwoDimensionCodeImage .java

     1 import jp.sourceforge.qrcode.data.QRCodeImage;
     2 
     3 import java.awt.image.BufferedImage;
     4 
     5 public class TwoDimensionCodeImage implements QRCodeImage {
     6     BufferedImage bufImg;  //将图片加载到内存中
     7     public TwoDimensionCodeImage(BufferedImage bufImg) {
     8         this.bufImg = bufImg;
     9     }
    10     public int getWidth() {
    11         return bufImg.getWidth();
    12     }
    13 
    14     public int getHeight() {
    15         return bufImg.getHeight();
    16     }
    17 
    18     public int getPixel(int x, int y) {
    19         return bufImg.getRGB(x,y);
    20     }
    21 }

     (3)Test .java

     1 public class Test {
     2     public static void main(String[] args)  throws Exception{
     3         //生成二维码
     4         /*
     5          * 生成图片的路径        src/二维码.png
     6          * 文字信息、网址信息 :  "helloworld"
     7          */
     8         String imgPath = "e:\二维码2.png";
     9         String content =  "http://baidu.com";  //扫描二维码后,网页跳转
    10 
    11         //生成二维码
    12         /*
    13          * 加密:  文字信息 ->二维码
    14          * 解密:  二维码 -> 文字信息
    15          */
    16         QRCodeUtil qrUtil = new QRCodeUtil();
    17         //加密:  文字信息 ->二维码
    18         qrUtil.encoderQRCode(content, imgPath, "png", 17);
    19 
    20 //           TwoDimensionCode handler = new TwoDimensionCode();
    21 //           handler.encoderQRCode(content, imgPath, "png", 7);
    22 
    23 
    24 //        //解密:  二维码 -> 文字信息
    25         String imgContent = qrUtil.decoderQRCode(imgPath) ;
    26         System.out.println(imgContent);
    27 
    28 
    29     }
    30 }

    第二种:借助Google提供的ZXing Core工具包

    1.maven依赖

     1  <dependency>
     2             <groupId>com.google.zxing</groupId>
     3             <artifactId>core</artifactId>
     4             <version>3.4.0</version>
     5         </dependency>
     6         <dependency>
     7             <groupId>com.google.zxing</groupId>
     8             <artifactId>javase</artifactId>
     9             <version>3.3.1</version>
    10         </dependency>

    2.代码

    (1)ZXingUtil .java

     1 import com.google.zxing.*;
     2 import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
     3 import com.google.zxing.common.BitMatrix;
     4 import com.google.zxing.common.HybridBinarizer;
     5 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
     6 import jp.sourceforge.qrcode.util.Color;
     7 
     8 import javax.imageio.ImageIO;
     9 import java.awt.image.BufferedImage;
    10 import java.io.File;
    11 import java.util.HashMap;
    12 import java.util.Hashtable;
    13 import java.util.Map;
    14 
    15 public class ZXingUtil {
    16     public static void encodeImg(String imgPath,String format,String content,int width,int height,String logo) throws Exception {
    17         Hashtable<EncodeHintType,Object > hints = new Hashtable<EncodeHintType,Object>() ;
    18         //排错率  L<M<Q<H
    19         hints.put( EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H) ;
    20         //编码
    21         hints.put( EncodeHintType.CHARACTER_SET, "utf-8") ;
    22         //外边距:margin
    23         hints.put( EncodeHintType.MARGIN, 1) ;
    24         /*
    25          * content : 需要加密的 文字
    26          * BarcodeFormat.QR_CODE:要解析的类型(二维码)
    27          * hints:加密涉及的一些参数:编码、排错率
    28          */
    29         BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,width,height, hints);
    30         //内存中的一张图片:此时需要的图片 是二维码-> 需要一个boolean[][] ->BitMatrix
    31         BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
    32 
    33         for(int x=0;x<width;x++) {
    34             for(int y=0;y<height;y++) {
    35                 image.setRGB(x, y,     (bitMatrix.get(x,y)? Color.BLACK:Color.WHITE)  );
    36             }
    37         }
    38         //画logo
    39         image = LogoUtil.logoMatrix(image, logo) ;
    40         //string->file
    41         File file = new File(imgPath);
    42         //生成图片
    43         ImageIO.write(image, format, file);
    44     }
    45 
    46     //解密:二维码->文字
    47     public static void decodeImg(File file) throws Exception {
    48         if(!file.exists()) return ;
    49         //file->内存中的一张图片
    50         BufferedImage imge = ImageIO.read(file)  ;
    51 
    52         MultiFormatReader formatReader = new MultiFormatReader() ;
    53         LuminanceSource source = new BufferedImageLuminanceSource(imge);
    54         Binarizer binarizer = new HybridBinarizer(source);
    55         BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
    56         //图片 ->result
    57         Map map = new HashMap();
    58         map.put(EncodeHintType.CHARACTER_SET, "utf-8") ;
    59         Result result = formatReader.decode(binaryBitmap  ,map ) ;
    60         System.out.println("解析结果:"+ result.toString());
    61     }
    62 
    63 }

    (2)LogoUtil .java

     1 import javax.imageio.ImageIO;
     2 import java.awt.*;
     3 import java.awt.geom.RoundRectangle2D;
     4 import java.awt.image.BufferedImage;
     5 import java.io.File;
     6 import java.io.IOException;
     7 
     8 public class LogoUtil {
     9     //传入logo、二维码 ->带logo的二维码
    10     public  static BufferedImage  logoMatrix( BufferedImage matrixImage,String logo ) throws IOException {
    11         //在二维码上画logo:产生一个  二维码画板
    12         Graphics2D g2 = matrixImage.createGraphics();
    13 
    14         //画logo: String->BufferedImage(内存)
    15         BufferedImage logoImg = ImageIO.read(new File(logo));
    16         int height = matrixImage.getHeight();
    17         int width = matrixImage.getWidth();
    18         //纯logo图片
    19         g2.drawImage(logoImg, width * 2 / 5, height * 2 / 5, width * 1 / 5, height * 1 / 5, null);
    20 
    21         //产生一个 画 白色圆角正方形的 画笔
    22         BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
    23         //将画板-画笔 关联
    24         g2.setStroke(stroke);
    25         //创建一个正方形
    26         RoundRectangle2D.Float round = new RoundRectangle2D.Float(width * 2 / 5, height * 2 / 5, width * 1 / 5, height * 1 / 5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
    27         g2.setColor(Color.WHITE);
    28         g2.draw(round);
    29 
    30         //灰色边框
    31         BasicStroke stroke2 = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
    32         g2.setStroke(stroke2);
    33         //创建一个正方形
    34         RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(width * 2 / 5 + 2, height * 2 / 5 + 2, width * 1 / 5 - 4, height * 1 / 5 - 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
    35 //        Color color = new Color(128,128,128) ;
    36         g2.setColor(Color.GRAY);
    37         g2.draw(round2);
    38 
    39         g2.dispose();
    40         matrixImage.flush();
    41 
    42         return matrixImage;
    43     }
    44 }

    (3)test.java

     1 import java.io.File;
     2 
     3 public class test {
     4     public static void main(String[] args) throws Exception {
     5         String imgPath = "src/二维码12.png";
     6         String content = "helloworld你好";
     7         String logo = "src/logo.png";
     8         //加密:文字信息->二维码
     9         ZXingUtil.encodeImg(imgPath, "png",content, 430, 430,logo);
    10         //解密:二维码  ->文字信息
    11         ZXingUtil.decodeImg(new File(imgPath));
    12     }
    13 }
    

    (效果图)

  • 相关阅读:
    关于工作习惯的一点思考
    BulkSqlCopy 批量导入数据(Ef支持)
    记录下最近项目中常用到的SQL语句
    对象化前端表单(Form)提交
    Python描述符 (descriptor) 详解
    Python装饰器之 property()
    Python魔法方法之属性访问 ( __getattr__, __getattribute__, __setattr__, __delattr__ )
    Python魔法方法总结及注意事项
    面向对象编程(二)
    面向对象编程(一)
  • 原文地址:https://www.cnblogs.com/codingcc1/p/11099788.html
Copyright © 2020-2023  润新知