引入:

现在有了微信,所以有了形形×××的二维码,特别是我天天赶地铁上班,在地铁站内充斥着各个二维码,还有火车票右下角都有二维码。其实我们这里经常用到的二维码是 QR二维码,它是由日本人发明的,是二维码的一种。

从大体上看,一般一个QR二维码结构如下,其中有3个定位标志,右下角是校验标志,还有一些定时标志,版本信息,格式信息,这些肉眼不能识别,但是特殊设备却能读取。

关于QR二维码的信息,可以参见以下文章:

实践:

我们这里就用JAVA代码来实现生成QR二维码图片以及如何从二维码图片中还原出原始文本内容,我们依然使用ZXing库:

package com.charles.study.barcode.twodimensions;import java.awt.p_w_picpath.BufferedImage;import java.io.File;import java.util.HashMap;import java.util.Hashtable;import java.util.Map;import javax.p_w_picpathio.ImageIO;import com.google.zxing.BarcodeFormat;import com.google.zxing.BinaryBitmap;import com.google.zxing.DecodeHintType;import com.google.zxing.EncodeHintType;import com.google.zxing.LuminanceSource;import com.google.zxing.MultiFormatReader;import com.google.zxing.MultiFormatWriter;import com.google.zxing.Result;import com.google.zxing.client.j2se.BufferedImageLuminanceSource;import com.google.zxing.client.j2se.MatrixToImageWriter;import com.google.zxing.common.BitMatrix;import com.google.zxing.common.HybridBinarizer;import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;/** * 这个工具类用于处理编码/解码 二维码 * @author charles.wang * */public class TwoDimensionCodeUtil {                                                                                                                            private TwoDimensionCodeUtil(){}                                                                                                                                                                                                                                                    /**     * 基于一个字符串生成相对应的QR二维码,有指定的宽度和高度,并且存放到指定位置的文件中     * @param contents     * @param width     * @param height     * @param fileName     * @throws Exception     */    public static void generate2DBarCodeImage(String contents ,int width,int height,String fileName) throws Exception{                                                                                                                                    //这里略去入参检查,因为不是重点                                                                                                                                                                                                                                                                //配置Q-R 二维码的信息        Hashtable hints= new Hashtable();        // 定义纠错等级         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);         // 指定二维码的编码规则        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");                                                                                                                                    //创建二维码对应的位图矩阵信息        BitMatrix bitMetrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height,hints);                                                                                                                                    //从入参获取文件格式        String fileFormat = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());        //从入参创建文件对象        File outputFile = new File(fileName);                                                                                                                                    //吧位图矩阵写入指定的图片文件中        MatrixToImageWriter.writeToFile(bitMetrix,fileFormat,outputFile);    }                                                                                                                                                                                                                                                    /**     * 读取一个QR二维码图片文件,还原其原始信息     * @param p_w_picpathPath     * @return     */    public static String resolve2DBarCodeImage(String p_w_picpathPath){                                                                                                                                    BufferedImage p_w_picpath = null;        try {                                                                                                                                             //读取二维码图片文件            p_w_picpath = ImageIO.read(new File(p_w_picpathPath));             if (p_w_picpath == null) {                 System.out.println("二维码图片不存在.");             }                                                                                                                                                 LuminanceSource source = new BufferedImageLuminanceSource(p_w_picpath);             BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));                                                                                                                                                                                                                                                                   //设置二维码的解码规则            Map
hints = new HashMap
(); hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); //基于二维码图片文件解码获得其结果 Result result = new MultiFormatReader().decode(bitmap,hints); //从结果中获得原始文本 return result.getText(); } catch (Exception e) { e.printStackTrace(); } return null; } public static void main(String [] args){ //二维码Demo //生成二维码 try{ String qr_contents= "Charles的二维码范例"; int qr_width = 200; int qr_height= 200; generate2DBarCodeImage(qr_contents,qr_width,qr_height,"D:/Framework Study/BarCode/TwoDimensions/newQRcode.png"); }catch(Exception ex){ System.err.print("生成二维码出错"); } //解析二维码 String qr_original = resolve2DBarCodeImage("D:/Framework Study/BarCode/TwoDimensions/newQRcode.png"); System.out.println("还原的信息为:"+qr_original); }}

我们做实验,当运行生成二维码部分时候,它会在D:/Framework Study/BarCode/TwoDimensions/newQRCode.png生成一个二维码图片文件,大小格式都符合:

我们查看这个二维码图片文件,显然,它说的特征符合我们开始介绍的QR二维码的特征:

然后我们运行下面的解析过程,则控制台显示:

说明我们的代码是完全正确的.

我还用了我同事的手机扫描了我这里生成的二维码信息,它会显示 ”Charles的二维码范例“文本在手机上。

福利:

这里提供一个在线网站可以专门去定制二维码: