zoukankan      html  css  js  c++  java
  • Java与JS生成二维码与条形码

      一般常见的是二维码和条形码,二维码常见类型是qrcode,二维码就是code128.扫码枪可以识别二维码,也可以识别条形码。扫码枪扫码其实是识别码中的内容并按下回车键。所以经常用条形码实现搜索等功能。二维码识别之后如果是URL地址一般会自动跳转,如果是普通的字符串会显示内容。  

    1.二维码概念

     二维码/二维条码是用某种特定的集合图形按一定规律在平面上(二维方向上)分布的黑白相间的图形记录数据符号信息的图片。

    黑线是二进制的1,空白的地方是二进制的0,通过1、0这种数据组合用于存储数据。

     

    2.二维码分类:

    二维码有不同的码制,就码制的编码原理而言,通常分为三类:

    1.线性堆叠式二维码

    2.矩阵式二维码(常用)  黑线、点是二进制的1,空白的地方是二进制的0,通过1、0这种数据组合用于存储数据。

    3.邮政码.一般用于邮件编码

    三、QRCode简介:

    qrcode是日本公司研发的一套标准,市面流行的也是qrcode。

    1.JSP生成QRCode的两种方式:

    (1)借助第三方jar,如zxing,qrcode.jar

    (2)javascript,例如:jquery.qrcode.js

     四、zxing实现生成和解析二维码

     1.下载源码并达成jar包。

    源码下载地址 https://github.com/zxing/zxing

     2.打成ajr包(将cor和javase目录下的文件打包)

    也可以直接到这里下载我导好的jar包:http://qiaoliqiang.cn/fileDown/zxing.jar

     3.导入项目开始生成二维码(可以将二维码生成到本地,也可以生成到输入流在网页中访问)

    生成二维码的代码:

    package zxing;
    
    import java.io.File;
    import java.nio.file.Path;
    import java.util.HashMap;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.WriterException;
    import com.google.zxing.client.j2se.MatrixToImageConfig;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    /**
     * 生成二维码图片
    * @author: qlq
    * @date :  2018年6月1日下午6:00:57
     */
    public class CreateQRCode {
    
        public static void main(String[] args) {
    
            int height = 300;//设置高度
            int width = 300;//设置宽度
            String format = "png";
            String content = "这里是二维码的内容";
            
            //设置二维码的参数
            HashMap hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");//设置编码格式
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//一般M够用
            hints.put(EncodeHintType.MARGIN, 2);//设置边距
            
            try {
                //编码
                BitMatrix bitMatrix =     new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height ,hints);
                //设置生成的路径
                Path path = new File("E:/zxing.png").toPath();
                //导出二维码(可以以流的形式在网页访问,也可以导出到本地)
    //            MatrixToImageWriter.writeToStream(matrix, format, stream);
                MatrixToImageWriter.writeToPath(bitMatrix, format, path);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            
            
        }
    
    }

     结果,E盘下生成二维码,扫描结果:  这里是二维码的内容

    补充:关于条形码和二维码

    QR_CODE是条形码

    CODE_128是二维码。

     4.zxing解析二维码内容

     代码:

    package zxing;
    
    import java.awt.event.MouseWheelEvent;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.HashMap;
    
    import javax.imageio.ImageIO;
    
    import com.google.zxing.Binarizer;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.LuminanceSource;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.NotFoundException;
    import com.google.zxing.Result;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.common.BitArray;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    
    /**
     * 读取二维码
    * @author: qlq
    * @date :  2018年6月1日下午6:01:55
     */
    public class ReadQRCode {
    
        public static void main(String[] args) throws IOException, NotFoundException {
            MultiFormatReader multiFormatReader = new MultiFormatReader();
            
            File file = new File("E:/zxing.png");
            
            BufferedImage bufferedImage = ImageIO.read(file);
            
            BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage)));
            
            //设置二维码的参数
            HashMap hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");//设置编码格式
            //读取二维码图片
            Result result = multiFormatReader.decode(binaryBitmap, hints);
            
            System.out.println("解析结果:"+result.toString());
            System.out.println("二维码格式类型:"+result.getBarcodeFormat());
            System.out.println("二维码文本内容:"+result.getText());
            
        }
    }

    结果:

    解析结果:这里是二维码的内容
    二维码格式类型:QR_CODE
    二维码文本内容:这里是二维码的内容

    五、qrcode实现生成和解析二维码(支持中间嵌入图片)

    1.qrcode生成二维码

    需要的jar包下载地址:   http://qiaoliqiang.cn/fileDown/qrcode/Qrcode_create.jar

    生成二维码的代码:

    package qrcode;
    
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    
    import com.swetake.util.Qrcode;
    
    /**
     * 生成二维码的图片
    * @author: qlq
    * @date :  2018年6月1日下午6:43:16
     */
    public class createQrcode {
        
        public static void main(String[] args) throws Exception {
            Qrcode qrcode = new Qrcode();
            qrcode.setQrcodeErrorCorrect('M');//纠错等级
            qrcode.setQrcodeEncodeMode('B');//N代表数字A代表a-Z,B代表其他字符
            qrcode.setQrcodeVersion(7);//版本号
            String content = "这是qrcode生成的二维码";
    //        int height = 300;
            //宽高要根据公式设置。67*12*(版本号-1)
            int height = 67 + 12 * (7 - 1);
            int width = 67 + 12 * (7 - 1);
            int pixoffset = 2;//偏移量,需要加偏移量,否则会报错
            
            
            BufferedImage bufferedImage =new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            
            Graphics2D graphics2d = bufferedImage.createGraphics();
            graphics2d.setBackground(Color.WHITE);
            graphics2d.setColor(Color.black);
            graphics2d.clearRect(0, 0, width, height);
            
            byte[] bytes = content.getBytes();
            if(bytes.length > 0 && bytes.length < 120){
                boolean [][] s = qrcode.calQrcode(bytes);
                for(int i=0;i<s.length;i++){
                    for(int j=0;j<s.length;j++){
                        if(s[i][j]){
                            graphics2d.fillRect(j*3, i*3, 3, 3);
                        }
                    }
                }
            }
            graphics2d.dispose();
            bufferedImage.flush();
            ImageIO.write(bufferedImage, "png", new File("E:/qrcode.png"));
            
        }
    }

    结果生成二维码,扫描结果是:  这是qrcode生成的二维码

    qrcode生成带图片的二维码:

    package qrcode;
    
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.io.File;
    
    import javax.imageio.ImageIO;
    
    import com.swetake.util.Qrcode;
    
    /**
     * 生成带图片的二维码
     * 
     * @author: qlq
     * @date : 2018年6月3日上午9:40:38
     */
    public class createImageQRCode {
        public static void main(String[] args) {
            createImageQRCode.QRCodeCreate("http://qiaoliqiang.cn","E:/qrImageCode.png",8,"C:/Users/liqiang/Desktop/文件/图片库/平时有用的图片/right.jpg");
        }
    
        /**
         * QRCode 方式生成带图片二维码
         * 
         * @param content
         *            二维码内容
         * @param imgPath
         *            二维码生成路径
         * @param version
         *            二维码版本
         * @param logoPath
         *            是否生成Logo图片 为NULL不生成
         */
        public static void QRCodeCreate(String content, String imgPath, int version, String logoPath) {
            try {
                Qrcode qrcodeHandler = new Qrcode();
                // 设置二维码排错率,可选L(7%) M(15%) Q(25%) H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小
                qrcodeHandler.setQrcodeErrorCorrect('M');
                // N代表数字,A代表字符a-Z,B代表其他字符
                qrcodeHandler.setQrcodeEncodeMode('B');
                // 版本1为21*21矩阵,版本每增1,二维码的两个边长都增4;所以版本7为45*45的矩阵;最高版本为是40,是177*177的矩阵
                qrcodeHandler.setQrcodeVersion(version);
                // 根据版本计算尺寸
                int imgSize = 67 + 12 * (version - 1);
                byte[] contentBytes = content.getBytes("gb2312");
                BufferedImage bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
                Graphics2D gs = bufImg.createGraphics();
                gs.setBackground(Color.WHITE);
                gs.clearRect(0, 0, imgSize, imgSize);
                // 设定图像颜色 > BLACK
                gs.setColor(Color.BLACK);
                // 设置偏移量 不设置可能导致解析出错
                int pixoff = 2;
                // 输出内容 > 二维码
                if (contentBytes.length > 0 && contentBytes.length < 130) {
                    boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);
                    for (int i = 0; i < codeOut.length; i++) {
                        for (int j = 0; j < codeOut.length; j++) {
                            if (codeOut[j][i]) {
                                gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
                            }
                        }
                    }
                } else {
                    System.err.println("QRCode content bytes length = " + contentBytes.length + " not in [ 0,130 ]. ");
                }
                /* 判断是否需要添加logo图片 */
                if (logoPath != null) {
                    File icon = new File(logoPath);
                    if (icon.exists()) {
                        int width_4 = imgSize / 4;
                        int width_8 = width_4 / 2;
                        int height_4 = imgSize / 4;
                        int height_8 = height_4 / 2;
                        Image img = ImageIO.read(icon);
                        gs.drawImage(img, width_4 + width_8, height_4 + height_8, width_4, height_4, null);
                        gs.dispose();
                        bufImg.flush();
                    } else {
                        System.out.println("Error: login图片不存在!");
                    }
    
                }
    
                gs.dispose();
                bufImg.flush();
                // 创建二维码文件
                File imgFile = new File(imgPath);
                if (!imgFile.exists())
                    imgFile.createNewFile();
                // 根据生成图片获取图片
                String imgType = imgPath.substring(imgPath.lastIndexOf(".") + 1, imgPath.length());
                // 生成二维码QRCode图片
                ImageIO.write(bufImg, imgType, imgFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    结果:

     2.qrcode读取二维码图片  (有点问题,建议使用zxing读取二维码,上面的读取方式)

     下载读取的jar包:   http://qiaoliqiang.cn/fileDown/qrcode/qrcode_read.jar

     代码:

    1.定义类实现QRCodeImage接口

    package qrcode;
    
    import java.awt.image.BufferedImage;
    
    import jp.sourceforge.qrcode.data.QRCodeImage;
    
    /**
     * 自定义读取qrcode的类
    * @author: qlq
    * @date :  2018年6月1日下午7:04:27
     */
    public class MyQrcodeImage implements QRCodeImage{
    
        private BufferedImage bufferedImage;
        
        public MyQrcodeImage(BufferedImage bufferedImage){
            this.bufferedImage  = bufferedImage;
        }
        @Override
        public int getHeight() {
            // TODO Auto-generated method stub
            return bufferedImage.getHeight();
        }
    
        @Override
        public int getPixel(int arg0, int arg1) {
            // TODO Auto-generated method stub
            return bufferedImage.getRGB(arg0, arg1);
        }
    
        @Override
        public int getWidth() {
            // TODO Auto-generated method stub
            return bufferedImage.getWidth();
        }
    
    }

     2.读取二维码的代码

    package qrcode;
    
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    
    import jp.sourceforge.qrcode.QRCodeDecoder;
    
    /**
     * qrcode读取二维码
     * 
     * @author: qlq
     * @date : 2018年6月1日下午7:07:00
     */
    public class QrcodeReadQRCode {
    
        public static void main(String[] args) throws IOException {
            File file = new File("E:/qrcode.png");
            BufferedImage bufferedImage = ImageIO.read(file);
            QRCodeDecoder decoder = new QRCodeDecoder();
            String result = new String(decoder.decode(new MyQrcodeImage(bufferedImage)),"utf-8");
            System.out.println(result);
        }
    }

    六、JS生成二维码(简单)

    原理也是生成一张图片,可以将图片保存到本地。可以生成带logo的二维码,内容可以设置中文。

    jquery-qrcode:  https://github.com/jeromeetienne/jquery-qrcode

    前提需要引入jQuery,也可以到我的下载链接直接下载对应的jQuery和qrcode的JS。http://qiaoliqiang.cn/fileDown/qrcode.js.zip

    生成二维码的例子如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>生成二维码</title>
        <script type="text/javascript" src="./JS/jquery.min.js"></script>
        <script type="text/javascript" src="./JS/jquery.qrcode.min.js"></script>
    </head>
    <body>
    生成的二维码如下:
    <div id="qrcode"></div>
    <br/>
    生成的指定宽度二维码如下:
    <div id="qrcode1"></div>
    <br/>
    生成的带logo的二维码如下:
    <div id="qrcode2"></div>
    
    <script>
        /*生成二维码,注意jQuery的Q要大写*/
        jQuery('#qrcode').qrcode("http://qiaoliqiang.cn");
        /*生成指定高度和宽度的二维码*/
        jQuery('#qrcode1').qrcode({ 64,height: 64,text: "http://qiaoliqiang.cn"});
        /*生成指定高度和宽度和带logo的二维码,且文字内容是中文*/
        jQuery('#qrcode2').qrcode({ 64,height: 64,src:'./image/left.jpg',text: toUtf8("欢迎你")});
    </script>
    </body>
    </html>

     注意:

      生成带logo的二维码的需要下载支持logo的qrcode.js,在我的下载地址的js是支持的。

      生成二维码的时候jQuery的Q要大写

    结果:

     七、二维码扩展:

    1.为什么我们扫描出来的是文本而不是连接?

    如果我们的url中没有协议,默认作为文本处理,如果路径加了协议会作为URL,扫描之后会跳转。

    qiaoliqiang.cn   改为   http://qiaoliqiang.cn

    2.如何实现扫描二维码之后安装软件?

     例如:安卓手机的下载地址:  http://xxxx.com/mobile/appdown/xxx.apk     (安卓手机的安装包后缀是apk)

      如果我们用浏览器或者其他自带的扫描是可以下载,但是微信不行,因为腾讯只有自己域名下的apk才可以通过扫一扫下载。

    3.如何实现二维码扫描名片?(重要)

    简单的话自己可以做一个网页实现,扫描的时候跳转到自己的网页即可。另外一种高大上的方式是VCard, Vcard是标准通信薄基本格式。

    VCard地址:https://en.wikipedia.org/wiki/VCard

    属性参考:https://blog.csdn.net/xfyangle/article/details/58601585

    内容遵从VCard规范,参考上面网站可以生成许多属性,建议使用zxing的方式在后台生成名片:

            String content = "BEGIN:VCARD"+"
    "
                    +"VERSION:4.0"+"
    "
                    +"N:乔;利强"+"
    "
                    +"FN:乔利强"+"
    "
                    +"EMAIL:qiao_liqiang@163.com"+"
    "
                    +"KIND:individual"+"
    "
                    +"LOGO;MEDIATYPE=image/png:http://qiaoliqiang.cn/fileDown/qlq.png"+"
    "
                    +"BDAY:1995-02-03"+"
    "
                    +"NOTE:我是一个好孩子!"+"
    "
                    +"NICKNAME:QiaoZhi"+"
    "
                    +"TEL;TYPE=cell:18434391711"+"
    "
                    +"URL:http://qiaoliqiang.cn"+"
    "
                    +"ORG:公司名称"+"
    "
                    +"TITLE:职位"+"
    "
                    +"x-qq:21588891"+"
    "
    //                +"HOBBY;LEVEL=high:knitting"+"
    "
    //                +"INTEREST;LEVEL=high:baseball"+"
    "
                    +"ADR;TYPE=home:;;123 Main St.;Springfield;IL;12345;USA"+"
    "
                    +"PHOTO;MEDIATYPE=image/jpeg:http://qiaoliqiang.cn/fileDown/qlq.jpeg"+"
    "
                    +"END:VCARD";

    扫描结果会变成一张名片:

  • 相关阅读:
    数据库隔离级别
    Mysql 命令详解
    Mysql 索引
    强化学习(四):蒙特卡洛方法
    强化学习(三):动态编程
    强化学习(二):马尔可夫决策过程
    强化学习(一): 引入
    自然语言处理(五)时下流行的生成模型
    论文选读三 QANet
    皮质学习 HTM 知多少
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/9122949.html
Copyright © 2011-2022 走看看