二维码生成_二维码生成原理 - CSDN
  • 最近项目中需要开发生成二维码的功能,方便使用手机支付,在网上查了一些资料,把用过的方法进行总结。 1.前端js生成二维码 demo下载:http://download.csdn.net/download/yin767833376/10165335 html页面代码: ...

    最近项目中需要开发生成二维码的功能,方便使用手机支付,在网上查了一些资料,把用过的方法进行总结。

    1.前端js生成二维码

    demo下载:http://download.csdn.net/download/yin767833376/10165335

    html页面代码:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <title></title>
    </head>
    <body>
    <script type="text/javascript" src="js/jquery-1.8.3.min.js" ></script>
    <script type="text/javascript" src="js/jquery.qrcode.js" ></script>
            <script type="text/javascript" src="js/qrcode.js" ></script> 
            <script type="text/javascript" src="js/utf.js" ></script>
    <p>Render in table</p>
    <div id="qrcodeTable"></div>
    <p>Render in canvas</p>
    <div id="qrcodeCanvas"></div>
    <script> 
        jQuery('#qrcodeTable').qrcode({
             render    : "table",                <!--二维码生成方式 -->
             text    : "http://www.baidu.com" , <!-- 二维码内容  -->
             width : "200",               //二维码的宽度
                     height : "200",
         });    
         jQuery('#qrcodeCanvas').qrcode({
          render    : "canvas",
             text    : "http://www.baidu.com",
             width : "200",               //二维码的宽度
                     height : "200",              //二维码的高度
                     background : "#ffffff",       //二维码的后景色
                     foreground : "#000000",        //二维码的前景色
                     src: 'img/gray.jpg'             //二维码中间的图片
         });
        
    </script>
    </body>
    </html>

    页面效果


    方法二:java生成二维码

    demo下载地址:http://download.csdn.net/download/yin767833376/10165628


    需要导入的jar包

    <!-- https://mvnrepository.com/artifact/com.google.zxing/javase -->
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>javase</artifactId>
        <version>3.3.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>core</artifactId>
        <version>3.3.1</version>
    </dependency>

    生成二维码的工具类,代码如下:

    package com.payplatform.util;


    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;


    import javax.imageio.ImageIO;


    import com.google.zxing.BarcodeFormat;
    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.WriterException;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    /**
     * Google zxing二维码工具类
     * 
     * @2017年12月20日
     * @author yinxf
     *
     */
    public class QRCodeUtil {
    //二维码颜色  
        private static final int BLACK = 0xFF000000;  
        //二维码颜色  
        private static final int WHITE = 0xFFFFFFFF;  
      
        public static void main(String[] args) throws Exception {
    zxingCodeCreate("http://www.baidu.com", 300, 300, "D:/qrcode.jpg", "jpg");
    //    zxingCodeAnalyze("D:/qrcode.jpg");
    }
        /** 
         * 生成二维码
         * @param text    二维码内容
         * @param width    二维码宽 
         * @param height    二维码高 
         * @param outPutPath    二维码生成保存路径 
         * @param imageType     二维码生成格式 
         */  
        public static void zxingCodeCreate(String text, int width, int height, String outPutPath, String imageType){  
            Map<EncodeHintType, String> his = new HashMap<EncodeHintType, String>();  
            //设置编码字符集  
            his.put(EncodeHintType.CHARACTER_SET, "utf-8");  
            try {  
                //1、生成二维码  
                BitMatrix encode = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, his);  
                  
                //2、获取二维码宽高  
                int codeWidth = encode.getWidth();  
                int codeHeight = encode.getHeight();  
                  
                //3、将二维码放入缓冲流  
                BufferedImage image = new BufferedImage(codeWidth, codeHeight, BufferedImage.TYPE_INT_RGB);  
                for (int i = 0; i < codeWidth; i++) {  
                    for (int j = 0; j < codeHeight; j++) {  
                        //4、循环将二维码内容定入图片  
                        image.setRGB(i, j, encode.get(i, j) ? BLACK : WHITE);  
                    }  
                }  
                File outPutImage = new File(outPutPath);  
                //如果图片不存在创建图片  
                if(!outPutImage.exists())  
                    outPutImage.createNewFile();  
                //5、将二维码写入图片  
                ImageIO.write(image, imageType, outPutImage);  
            } catch (WriterException e) {  
                e.printStackTrace();  
                System.out.println("二维码生成失败");  
            } catch (IOException e) {  
                e.printStackTrace();  
                System.out.println("生成二维码图片失败");  
            }  
        }  
          
        /** 
         * 二维码解析 
         * @param analyzePath    二维码路径 
         * @return 
         * @throws IOException 
         */  
        @SuppressWarnings({ "rawtypes", "unchecked" })  
        public static String zxingCodeAnalyze(String analyzePath) throws Exception{  
            MultiFormatReader formatReader = new MultiFormatReader();  
            String resultStr = null;  
            try {  
                File file = new File(analyzePath);  
                if (!file.exists())  
                {  
                    return "二维码不存在";  
                }  
                BufferedImage image = ImageIO.read(file);  
                LuminanceSource source = new BufferedImageLuminanceSource(image);  
                Binarizer binarizer = new HybridBinarizer(source);    
                BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);  
                Map hints = new HashMap();  
                hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");  
                Result result = formatReader.decode(binaryBitmap, hints); 
                resultStr = result.getText();
            } catch (NotFoundException e) {  
                e.printStackTrace();  
            }    
            return resultStr;  
        }  
          
    }

    以上两种方法均已测试通过,可以直接下载demo运行,查看运行效果。

    展开全文
  • 二维码生成

    2020-07-30 23:32:04
    Java二维码生成器,既可以有图片,也可以没有图片的二维码生成器。。。。
  • 二维码生成细节和原理

    万次阅读 多人点赞 2016-03-09 23:10:39
    二维码又称QR Code,QR全称Quick Response,...这两天学习了一下二维码图片生成的相关细节,觉得这个玩意就是一个密码算法,在此写一这篇文章 ,揭露一下。供好学的人一同学习之。 关于QR Code Specification,可参

    二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型:比如:字符,数字,日文,中文等等。这两天学习了一下二维码图片生成的相关细节,觉得这个玩意就是一个密码算法,在此写一这篇文章 ,揭露一下。供好学的人一同学习之。

    关于QR Code Specification,可参看这个PDF:http://raidenii.net/files/datasheets/misc/qr_code.pdf 

    基础知识

    首先,我们先说一下二维码一共有40个尺寸。官方叫版本Version。Version 1是21 x 21的矩阵,Version 2是 25 x 25的矩阵,Version 3是29的尺寸,每增加一个version,就会增加4的尺寸,公式是:(V-1)*4 + 21(V是版本号) 最高Version 40,(40-1)*4+21 = 177,所以最高是177 x 177 的正方形。

    下面我们看看一个二维码的样例:

    定位图案
    • Position Detection Pattern是定位图案,用于标记二维码的矩形大小。这三个定位图案有白边叫Separators for Postion Detection Patterns。之所以三个而不是四个意思就是三个就可以标识一个矩形了。
    • Timing Patterns也是用于定位的。原因是二维码有40种尺寸,尺寸过大了后需要有根标准线,不然扫描的时候可能会扫歪了。
    • Alignment Patterns 只有Version 2以上(包括Version2)的二维码需要这个东东,同样是为了定位用的。
    功能性数据
    • Format Information 存在于所有的尺寸中,用于存放一些格式化数据的。
    • Version Information 在 >= Version 7以上,需要预留两块3 x 6的区域存放一些版本信息。
    数据码和纠错码
    • 除了上述的那些地方,剩下的地方存放 Data Code 数据码 和 Error Correction Code 纠错码。

    数据编码

    我们先来说说数据编码。QR码支持如下的编码:

    Numeric mode 数字编码,从0到9。如果需要编码的数字的个数不是3的倍数,那么,最后剩下的1或2位数会被转成4或7bits,则其它的每3位数字会被编成 10,12,14bits,编成多长还要看二维码的尺寸(下面有一个表Table 3说明了这点)

    Alphanumeric mode 字符编码。包括 0-9,大写的A到Z(没有小写),以及符号$ % * + – . / : 包括空格。这些字符会映射成一个字符索引表。如下所示:(其中的SP是空格,Char是字符,Value是其索引值) 编码的过程是把字符两两分组,然后转成下表的45进制,然后转成11bits的二进制,如果最后有一个落单的,那就转成6bits的二进制。而编码模式和字符的个数需要根据不同的Version尺寸编成9, 11或13个二进制(如下表中Table 3)

    Byte mode, 字节编码,可以是0-255的ISO-8859-1字符。有些二维码的扫描器可以自动检测是否是UTF-8的编码。

    Kanji mode 这是日文编码,也是双字节编码。同样,也可以用于中文编码。日文和汉字的编码会减去一个值。如:在0X8140 to 0X9FFC中的字符会减去8140,在0XE040到0XEBBF中的字符要减去0XC140,然后把结果前两个16进制位拿出来乘以0XC0,然后再加上后两个16进制位,最后转成13bit的编码。如下图示例:

    Extended Channel Interpretation (ECI) mode 主要用于特殊的字符集。并不是所有的扫描器都支持这种编码。

    Structured Append mode 用于混合编码,也就是说,这个二维码中包含了多种编码格式。

    FNC1 mode 这种编码方式主要是给一些特殊的工业或行业用的。比如GS1条形码之类的。

    简单起见,后面三种不会在本文 中讨论。

    下面两张表中,

    • Table 2 是各个编码格式的“编号”,这个东西要写在Format Information中。注:中文是1101
    • Table 3 表示了,不同版本(尺寸)的二维码,对于,数字,字符,字节和Kanji模式下,对于单个编码的2进制的位数。(在二维码的规格说明书中,有各种各样的编码规范表,后面还会提到)

    下面我们看几个示例,

    示例一:数字编码

    在Version 1的尺寸下,纠错级别为H的情况下,编码: 01234567

    1. 把上述数字分成三组: 012 345 67

    2. 把他们转成二进制:  012 转成 0000001100;  345 转成 0101011001;  67 转成 1000011。

    3. 把这三个二进制串起来: 0000001100 0101011001 1000011

    4. 把数字的个数转成二进制 (version 1-H是10 bits ): 8个数字的二进制是 0000001000

    5. 把数字编码的标志0001和第4步的编码加到前面:  0001 0000001000 0000001100 0101011001 1000011

    示例二:字符编码

    在Version 1的尺寸下,纠错级别为H的情况下,编码: AC-42

    1. 从字符索引表中找到 AC-42 这五个字条的索引 (10,12,41,4,2)

    2. 两两分组: (10,12) (41,4) (2)

    3.把每一组转成11bits的二进制:

    (10,12) 10*45+12 等于 462 转成 00111001110
    (41,4) 41*45+4 等于 1849 转成 11100111001
    (2) 等于 2 转成 000010

    4. 把这些二进制连接起来:00111001110 11100111001 000010

    5. 把字符的个数转成二进制 (Version 1-H为9 bits ): 5个字符,5转成 000000101

    6. 在头上加上编码标识 0010 和第5步的个数编码:  0010 000000101 00111001110 11100111001 000010

    结束符和补齐符

    假如我们有个HELLO WORLD的字符串要编码,根据上面的示例二,我们可以得到下面的编码,

    编码 字符数 HELLO WORLD的编码
    0010 000001011 01100001011 01111000110 10001011100 10110111000 10011010100 001101

    我们还要加上结束符:

    编码 字符数 HELLO WORLD的编码 结束
    0010 000001011 01100001011 01111000110 10001011100 10110111000 10011010100 001101 0000
    按8bits重排

    如果所有的编码加起来不是8个倍数我们还要在后面加上足够的0,比如上面一共有78个bits,所以,我们还要加上2个0,然后按8个bits分好组:

    00100000   01011011   00001011   01111000   11010001   01110010   11011100   01001101   01000011   01000000

    补齐码(Padding Bytes)

    最后,如果如果还没有达到我们最大的bits数的限制,我们还要加一些补齐码(Padding Bytes),Padding Bytes就是重复下面的两个bytes:11101100 00010001 (这两个二进制转成十进制是236和17,我也不知道为什么,只知道Spec上是这么写的)关于每一个Version的每一种纠错级别的最大Bits限制,可以参看QR Code Spec的第28页到32页的Table-7一表。

    假设我们需要编码的是Version 1的Q纠错级,那么,其最大需要104个bits,而我们上面只有80个bits,所以,还需要补24个bits,也就是需要3个Padding Bytes,我们就添加三个,于是得到下面的编码:

    00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 01000000 11101100 00010001 11101100

    上面的编码就是数据码了,叫Data Codewords,每一个8bits叫一个codeword,我们还要对这些数据码加上纠错信息。

    纠错码

    上面我们说到了一些纠错级别,Error Correction Code Level,二维码中有四种级别的纠错,这就是为什么二维码有残缺还能扫出来,也就是为什么有人在二维码的中心位置加入图标。

    错误修正容量
    L水平 7%的字码可被修正
    M水平 15%的字码可被修正
    Q水平 25%的字码可被修正
    H水平 30%的字码可被修正

    那么,QR是怎么对数据码加上纠错码的?首先,我们需要对数据码进行分组,也就是分成不同的Block,然后对各个Block进行纠错编码,对于如何分组,我们可以查看QR Code Spec的第33页到44页的Table-13到Table-22的定义表。注意最后两列:

    • Number of Error Code Correction Blocks :需要分多少个块。
    • Error Correction Code Per Blocks:每一个块中的code个数,所谓的code的个数,也就是有多少个8bits的字节。

    举个例子:上述的Version 5 + Q纠错级:需要4个Blocks(2个Blocks为一组,共两组),头一组的两个Blocks中各15个bits数据 + 各 9个bits的纠错码(注:表中的codewords就是一个8bits的byte)(再注:最后一例中的(c, k, r )的公式为:c = k + 2 * r,因为后脚注解释了:纠错码的容量小于纠错码的一半)

    下图给一个5-Q的示例(因为二进制写起来会让表格太大,所以,我都用了十进制,我们可以看到每一块的纠错码有18个codewords,也就是18个8bits的二进制数)

    数据 对每个块的纠错码
    1 1 67 85 70 134 87 38 85 194 119 50 6 18 6 103 38 213 199 11 45 115 247 241 223 229 248 154 117 154 111 86 161 111 39
    2 246 246 66 7 118 134 242 7 38 86 22 198 199 146 6 87 204 96 60 202 182 124 157 200 134 27 129 209 17 163 163 120 133
    2 1 182 230 247 119 50 7 118 134 87 38 82 6 134 151 50 7 148 116 177 212 76 133 75 242 238 76 195 230 189 10 108 240 192 141
    2 70 247 118 86 194 6 151 50 16 236 17 236 17 236 17 236 235 159 5 173 24 147 59 33 106 40 255 172 82 2 131 32 178 236

    注:二维码的纠错码主要是通过Reed-Solomon error correction(里德-所罗门纠错算法)来实现的。对于这个算法,对于我来说是相当的复杂,里面有很多的数学计算,比如:多项式除法,把1-255的数映射成2的n次方(0<=n<=255)的伽罗瓦域Galois Field之类的神一样的东西,以及基于这些基础的纠错数学公式,因为我的数据基础差,对于我来说太过复杂,所以我一时半会儿还有点没搞明白,还在学习中,所以,我在这里就不展开说这些东西了。还请大家见谅了。(当然,如果有朋友很明白,也繁请教教我)

    最终编码

    穿插放置

    如果你以为我们可以开始画图,你就错了。二维码的混乱技术还没有玩完,它还要把数据码和纠错码的各个codewords交替放在一起。如何交替呢,规则如下:

    对于数据码:把每个块的第一个codewords先拿出来按顺度排列好,然后再取第一块的第二个,如此类推。如:上述示例中的Data Codewords如下:

    块 1 67 85 70 134 87 38 85 194 119 50 6 18 6 103 38  
    块 2 246 246 66 7 118 134 242 7 38 86 22 198 199 146 6  
    块 3 182 230 247 119 50 7 118 134 87 38 82 6 134 151 50 7
    块 4 70 247 118 86 194 6 151 50 16 236 17 236 17 236 17 236

    我们先取第一列的:67, 246, 182, 70

    然后再取第二列的:67, 246, 182, 70, 85,246,230 ,247

    如此类推:67, 246, 182, 70, 85,246,230 ,247 ………  ……… ,38,6,50,17,7,236

    对于纠错码,也是一样:

    块 1 213 199 11 45 115 247 241 223 229 248 154 117 154 111 86 161 111 39
    块 2 87 204 96 60 202 182 124 157 200 134 27 129 209 17 163 163 120 133
    块 3 148 116 177 212 76 133 75 242 238 76 195 230 189 10 108 240 192 141
    块 4 235 159 5 173 24 147 59 33 106 40 255 172 82 2 131 32 178 236

    和数据码取的一样,得到:213,87,148,235,199,204,116,159,…… …… 39,133,141,236

    然后,再把这两组放在一起(纠错码放在数据码之后)得到:

    67, 246, 182, 70, 85, 246, 230, 247, 70, 66, 247, 118, 134, 7, 119, 86, 87, 118, 50, 194, 38, 134, 7, 6, 85, 242, 118, 151, 194, 7, 134, 50, 119, 38, 87, 16, 50, 86, 38, 236, 6, 22, 82, 17, 18, 198, 6, 236, 6, 199, 134, 17, 103, 146, 151, 236, 38, 6, 50, 17, 7, 236, 213, 87, 148, 235, 199, 204, 116, 159, 11, 96, 177, 5, 45, 60, 212, 173, 115, 202, 76, 24, 247, 182, 133, 147, 241, 124, 75, 59, 223, 157, 242, 33, 229, 200, 238, 106, 248, 134, 76, 40, 154, 27, 195, 255, 117, 129, 230, 172, 154, 209, 189, 82, 111, 17, 10, 2, 86, 163, 108, 131, 161, 163, 240, 32, 111, 120, 192, 178, 39, 133, 141, 236

    这就是我们的数据区。

    Remainder Bits

    最后再加上Reminder Bits,对于某些Version的QR,上面的还不够长度,还要加上Remainder Bits,比如:上述的5Q版的二维码,还要加上7个bits,Remainder Bits加零就好了。关于哪些Version需要多少个Remainder bit,可以参看QR Code Spec的第15页的Table-1的定义表。

    画二维码图

    Position Detection Pattern

    首先,先把Position Detection图案画在三个角上。(无论Version如何,这个图案的尺寸就是这么大)

    Alignment Pattern

    然后,再把Alignment图案画上(无论Version如何,这个图案的尺寸就是这么大)

    关于Alignment的位置,可以查看QR Code Spec的第81页的Table-E.1的定义表(下表是不完全表格)

    下图是根据上述表格中的Version8的一个例子(6,24,42)

    Timing Pattern

    接下来是Timing Pattern的线(这个不用多说了)

    Format Information

    再接下来是Formation Information,下图中的蓝色部分。

    Format Information是一个15个bits的信息,每一个bit的位置如下图所示:(注意图中的Dark Module,那是永远出现的)

    这15个bits中包括:

    • 5个数据bits:其中,2个bits用于表示使用什么样的Error Correction Level, 3个bits表示使用什么样的Mask
    • 10个纠错bits。主要通过BCH Code来计算

    然后15个bits还要与101010000010010做XOR操作。这样就保证不会因为我们选用了00的纠错级别和000的Mask,从而造成全部为白色,这会增加我们的扫描器的图像识别的困难。

    下面是一个示例:

    关于Error Correction Level如下表所示:

    关于Mask图案如后面的Table 23所示。

    Version Information

    再接下来是Version Information(版本7以后需要这个编码),下图中的蓝色部分。

    Version Information一共是18个bits,其中包括6个bits的版本号以及12个bits的纠错码,下面是一个示例:

    而其填充位置如下:

    数据和数据纠错码

    然后是填接我们的最终编码,最终编码的填充方式如下:从左下角开始沿着红线填我们的各个bits,1是黑色,0是白色。如果遇到了上面的非数据区,则绕开或跳过。

    掩码图案

    这样下来,我们的图就填好了,但是,也许那些点并不均衡,如果出现大面积的空白或黑块,会告诉我们扫描识别的困难。所以,我们还要做Masking操作(靠,还嫌不复杂)QR的Spec中说了,QR有8个Mask你可以使用,如下所示:其中,各个mask的公式在各个图下面。所谓mask,说白了,就是和上面生成的图做XOR操作。Mask只会和数据区进行XOR,不会影响功能区。(注:选择一个合适的Mask也是有算法的

    其Mask的标识码如下所示:(其中的i,j分别对应于上图的x,y)

    下面是Mask后的一些样子,我们可以看到被某些Mask XOR了的数据变得比较零散了。

    Mask过后的二维码就成最终的图了。

    好了,大家可以去尝试去写一下QR的编码程序,当然,你可以用网上找个Reed Soloman的纠错算法的库,或是看看别人的源代码是怎么实现这个繁锁的编码。

    (全文完)

    展开全文
  • 超级方便实用二维码生成器,再也不用去各种网站注册登录制作二维码了!

    你好,我是goldsun

    你有想法和我一起进步吗?

    开头说两局

    不知不觉,自己来到CSDN竟然已经写了20来篇文章了,甚至其中还有超过上万字的,从小语文就异常差劲的我从来没想过自己的未来竟然也会写文章哈哈哈。不过这不是重点,重点是当我写了文章之后,可能不止我,或许很多很多写了文章的人吧,肯定是希望自己的文章能被更多的人看到的,可是看着我这很一般的阅读量:
    在这里插入图片描述
    没想到竟然还有阅读20多的,实在是让我很难以接受啊,然后我就自己想着能否在朋友圈什么的社交平台给自己推广一波哈哈,然后刚开始想着直接用CSDN的用户名片那个二维码让大家有兴趣的人都关注下,二维码如图:
    在这里插入图片描述

    可是我觉得好像有点LOW哎(希望别伤了CSDN二维码设计者的心,仅个人观点嘻嘻),突然想到能不能用二维码把自己的博客地址发出去,这样大家扫了之后不但能推广,还能顺便看看我写的文章怎么样。于是乎,我顺手一百度,果然全是各种二维码在线生成网站哒哒哒,可是我进去看了一圈下来,好烦啊基本上都得先注册登录网站才能进行下一步,我一想万一手机号随便乱注册以后各种推销电话可能就越来越多了,于是我就想是否能用Python生成二维码,再百度一下,哎呀,果真有,而且还有不止一种方法,于是乎,经过分析各大网友提供的方法,我找到了一种我认为是最简单的使用方法:
    利用myqr这个第三方库
    利用这个第三方库的话在命令行只需要一行代码,即使利用python解释器写个程序也不需要太多代码,下面是官方示例:
    在这里插入图片描述
    写成Python程序的方式:
    在这里插入图片描述
    官方示例的效果图:
    在这里插入图片描述
    在这里插入图片描述
    项目地址:https://github.com/sylnsfar/qrcode/
    说实话,当我看到这些图片特别是下面这个动态图的时候,我人都傻了,怎么可以这么好看!!!我也迫不及待的做了一张二维码,说实话效果很不错,不过我又感觉好像即使只用一点代码就能生成二维码我还是感觉麻烦,毕竟如果生成各种二维码的时候还得更改各种参数,还得对比看来看去,我就想着做一个图形用户界面的程序吧,打包了之后每次运行就可以,并且各种参数什么的要就选上,不要就不选,是不是很方便,于是就开始做了!
    这是我的效果图:
    在这里插入图片描述
    怎么样,还不错吧嘻嘻。

    制作步骤

    Python能做图形界面的库不止一个,而我是个新手,选择了自己使用过的并且感觉比较好的库:
    tkinter

    我的思路很简单,总结下来8个字:

    Created with Raphaël 2.2.0设置界面添加功能

    tkinter是个功能很强大并且功能很多的一个库,其实我也有很多功能什么没用过,不过万幸我生活在一个开源的时代哈哈哈,随便网上找了一个模板,代码复制过来,简单看下哪个方法什么的代表哪个功能,就开始制作了。

    完整代码

    完整代码的话没有超过二百行,我已经放在我的github仓库了,仓库地址:
    https://github.com/goldsunC/Qr-code-generator
    或者你可以选择扫描我利用此二维码生成器生成的二维码进入仓库:
    在这里插入图片描述
    仓库文档有详细的使用方法说明,你可以直接下载源代码自己进行改动什么的,当然,你也可以直接打包。
    不过,要注意一点事情,这在github文档中会有说明。

    最后,如果感觉文章或代码有用,欢迎点赞!欢迎star!

    展开全文
  • 二维码生成原理及解析代码

    千次阅读 2019-06-14 17:38:19
    这里秉着好奇心,研究一下二维码生成,并尝试性写一个二维码解析源码。 一. 二维码基本知识 二维码另一个名称是QR Code(Quick Response Code),近年来在移动设备上经常使用,与传统条形码相比,可以存储更多的...

    自从大街小巷的小商小贩都开始布满了腾讯爸爸和阿里爸爸的二维码之后,我才感觉到我大天朝共享支付的优越性。最近毕业论文写的差不多了,在入职之前多学一些东西也是好的。这里秉着好奇心,研究一下二维码的生成,并尝试性写一个二维码解析源码。

    一. 二维码基本知识

    二维码另一个名称是QR Code(Quick Response Code),近年来在移动设备上经常使用,与传统条形码相比,可以存储更多的信息。二维码本质上是个密码算法,基本知识总结如下。 
    首先,二维码存在 40 种尺寸,在官方文档中,尺寸又被命名为 Version。尺寸与 Version 存在线性关系:Version 1 是 21×21 的矩阵,Version 2 是 25×25 的矩阵,每增加一个 Version,尺寸都会增加 4,故尺寸 Size 与 Version 的线性关系为:

     

    Size=(Version−1)×4Size=(Version−1)×4

     

    Version 的最大值是 40,故尺寸最大值是(40-1)*4+21 = 177,即 177 x 177 的矩阵。

    二维码结构如下图 1.1 所示: 
     
    图1.1 二维码结构 

     

    二维码的各部分都有自己的作用,基本上可被分为定位、功能数据、数据内容三部分。

    • 定位图案: 
      • Position Detection Pattern, 定位图案:用于标记二维码矩形的大小;用三个定位图案即可标识并确定一个二维码矩形的位置和方向了;
      • Separators for Position Detection Patterns, 定位图案分割器:用白边框将定位图案与其他区域区分;
      • Timing Patterns, 时序图案:用于定位,二维码如果尺寸过大,扫描时容易畸变,时序图案的作用就是防止扫描时畸变的产生;
      • Alignment Patterns, 对齐图案:只有在 Version 2 及其以上才会需要;
    • 功能数据: 
      • Format Information, 格式信息:存在于所有尺寸中,存放格式化数据;
      • Version Information, 版本信息:用于 Version 7 以上,需要预留两块 3×6 的区域存放部分版本信息;
    • 数据内容:剩余部分存储数据内容 
      • Data Code, 数据码;
      • Error Correction Code, 纠错码;

    二. 数据编码

    2.1 数据编码信息

    二维码的数据编码信息如下图 2.1, 2.2 中的列表所示: 
     
    图2.1 模式编号指示器 

     

     


     
    图2.2 字符计数指示器中的位数 

     

    上图 2.1 中,展示的是二维码支持的数据编码模式。 
    :其中中文编码模式为 1101;

    上图 2.2 中展示了不同版本(即不同尺寸)的二维码,单个编码对应二进制的位数。 
    :二维码规格说明书中,存在各式各样的编码规范表;

    图2.1, 2.2 表格具体含义,在后面的例程中会具体讲解。

    2.2 数据编码形式

    2.2.1 数字编码(Numeric Mode)

    数字编码的范围为 0~9。 
    对于数字编码,统计需要编码数字的个数是否为 3 的倍数:如果不是 3 的倍数,则剩下的 1 位或 2 位会被转为 4bits 或 8bits(十进制转二进制),每三位数字都会被编成 10bits, 12bits, 14bits,具体编码长度仍然需要二维码尺寸决定。

    2.2.2 字符编码(Alphanumeric Mode)

    字符编码的范围有:

    • 数字 0~9;
    • 大写 A~Z(无小写);
    • 几个符号$ % * + - . / 和空格。

    上述字符映射为一个索引表,如下图 2.3 所示: 

    图2.3 字符映射索引表 

     

    图中 Char 表示字符,Value 表示字符对应的索引值。 
    索引表中共 45 种对应关系,字符编码的过程,就是将每两个字符分为一组,然后转成上图 2.3 的 45 进制,再转为 11bits 的二进制结果。对于落单的一个字符,则转为 6bits 的二进制结果。 
    此外,根据上图 2.2 的设定,对不同 Version 的二维码使用 9/11/13 个二进制表示。

    注: 
    上图 2.3 中的 SP 代表空格。

    2.2.3 字节编码(Byte Mode)

    可以是 0-255 的 ISO-8859-1 字符。有些二维码的扫描器可以自动检测是否是 UTF-8 的编码。

    2.2.4 日文编码(Kanji Mode)

    日文编码同时也是双字节编码,同样也可以用于中文编码。 
    日文与中文编码流程基本相似:

    1. 首先减去一个值;
    2. 挑出差值结果的前两个 16 进制,乘以 0xC0;
    3. 加上后两个 16 进制位;
    4. 转为 13bits 编码;

    按照日文编码集 SHIFT_JIS为参照,可查询日文字符的对应编码。以“雅”与“芒”为例,转换过程如下图 2.4 所示: 
     
    图2.4 日文编码流程展示 

     

    2.2.5 其他编码

    其他类型的编码本文中不详细说明。其中包括:

    • 特殊字符集(Extended Channel Interpretation Mode):主要用于特殊的字符集,并不是所有的扫描器都支持这种编码;
    • 混合编码(Structured Append Mode):说明该二维码中包含了多种编码格式;
    • 特殊行业编码(FNC1 Mode):主要是给一些特殊的工业或行业用的,如GS1条形码等;

    2.3 数据编码示例说明

    分别用一个数字编码与字符编码的示例,说明数据编码的过程:

    2.3.1 例程1:数字编码

    问题:对于 Version 1 尺寸的二维码,纠错级别为 H,编码为:01234567 
    解析步骤:

    1. 将上述数字分为三组:012, 345, 67;
    2. 查询图 2.2 表格内容,Version 1 二维码的数字编码应转换为 10bits 的二进制数字,故将上面三组数字转为二进制分别为:012→0000001100, 345→0101011001, 67→1000011;
    3. 将三个二进制串连接起来:0000001100 0101011001 1000011;
    4. 将数字的个数转成二进制:对于数字编码,数字长度依旧用图 2.2 表格中查到的 10bits 二进制数字来表示,数字共有 8 个,故数字个数的二进制形式为:8→0000001000;
    5. 查询图 2.1 表格内容,数字编码的标志为 0001,将编码标志与步骤 4 编码结果加到步骤 3 结果之前,故最终结果为:0001 0000001000 0000001100 0101011001 1000011

    2.3.2 例程2:字符编码

    问题:对于 Version 1 尺寸的二维码,纠错级别为 H,编码为:AE-86 
    解析步骤:

    1. 在图 2.3 的字符索引表中分别找到 AE-86 五个字符的索引分别为:(10, 14, 41, 8, 6);
    2. 将五个字符两两分组:(10, 14) (41, 8) (6);
    3. 字符编码应将字符组转换为 11bits 的二进制,故上述三组字符首先转为 45 进制后再转为二进制: 
      • (10, 14):转为 45 进制:10×45+14=464;再转为 11bits 的二进制:00111010000;
      • (41, 8):转为 45 进制:41×45+8=1853;再转为 11bits 的二进制:11100111101;
      • (6):转为 45 进制:6;再转为 6bits 的二进制:000110;
    4. 将步骤 3 中得到的三个二进制结果连接起来:00111010000 11100111101 000110;
    5. 查询图 2.2 表格内容,Version 1 二维码的字符个数应转换为 9bits 的二进制数字,对于 5 个字符,二维码字符个数转为 9bits 二进制为:000000101;
    6. 查询图 2.1 表格内容,字符编码的标志为 0010,将编码标志与步骤 5 编码结果加到步骤 4 结果之前,故最终编码结果为:0010 000000101 00111010000 11100111101 000110;

    三. 结束符与补齐符

    对于结束符和补齐符,我们直接举例进行说明。 
    问题:对于 Version 1 尺寸的二维码,纠错级别为 H,以笔者的英文名作为编码:CHANDLERGENG 
    按照 2.3.2 字符编码例程进行分析,得到编码如下:

    编码 字符数 CHANDLERGENG 的编码
    0010 000001101 01000101101 00111011001 01001011110 01010010001 01011011110 10000011011

    3.1 结束符

    在需要在对于上述字符的编码,需要在最后加上结束符。结束符为连续 4 个 0 值。加上结束符后,得到的编码如下:

    编码 字符数 CHANDLERGENG 的编码 结束
    0010 000001101 01000101101 00111011001 01001011110 01010010001 01011011110 10000011011 0000

    如果所有的编码加起来不是 8 的倍数,则还需要在后面加上足够的 0。如上面一共有 83bits,所以与 8 的倍数还相差两位,故在最后加上 5 个 0,上表最终的数据变为: 
    00100000 01101010 00101101 00111011 00101001 01111001 01001000 10101101 11101000 00110110 00000000

    3.2 补齐符

    如果最后还没有达到我们最大的 Bits 数限制,则需要在编码最后加上补齐符(Padding Bytes)。 
    补齐符内容是不停重复两个字节:11101100 和 00010001。这两个二进制转成十进制,分别为 236 与17,具体不知道为什么选这两个值……关于每一个Version的每一种纠错级别的最大Bits限制,可以参看 QR Code Spec 的第35页到44页的 Table-7 一表(笔者参考的是《ISO/IEC 18004》2000版),大致如下图 3.1 所示:

     
    图3.1 二维码纠错级别的最大Bits限制(部分) 

     

    上图 3.1 中提到的 codewords,可译为码字,一个码字是一个字节。对于 Version 1 的 H 纠错级别,共需要 26 个码字,即 104bits(应该是208bits?)。现在加上用 0 补全的结束符,已经有了 88bits,故还需要补上 16 bits。补齐后的编码为:

    00100000 01101010 00101101 00111011 00101001 01111001 01001000 10101101 11101000 00110110 00000000 11101100 00010001

    以上数据即为数据码(Data Codewords)

    四. 纠错码

    前文提到了不同的纠错级别(Error Correction Code Level)。有了纠错机制,才可以使得有些二维码有了残缺也可以扫码解析出来,才可以使得二维码中心位置可以供某些商家加上对解析不必要的图标。 
    二维码一共有四种纠错级别:

    纠错水平 可被修正容量
    L 7% 码字
    M 15% 码字
    Q 25% 码字
    H 30% 码字

    二维码对数据码加上纠错码的过程,首先要对数据码进行分组,即分成不同的块(Block)。参看如上图 3.1 所示 QR Code Spec 的第35页到44页的 Table-7 中的最下方说明了分组的定义表:

     


     
    图4.1 二维码纠错级别说明(部分) 


    对于表中的最后两列的内容:

     

    • 纠错块个数(Number of error correction blocks):需要划分纠错快的个数;
    • 纠错块码字数(Error Correction Code Per Blocks):每个块中的码字个数,即有多少个字节Bytes;

    表中最下面关于 (c,k,r) 的解释:

    • c:码字总个数;
    • k:数据码个数;
    • r:纠错码容量

    注:

    • c,k,r的关系公式:c=k+2×rc=k+2×r。
    • 纠错码容量小于纠错码个数的一半

    以上图 4.1 中的 Version 5 + H 纠错机为例:图中红色方框说明共需要 4 个块(上下行各一组,每组 2 个块)。

    第一组的属性:

    • 纠错块个数 = 2:该组中有两个块;
    • (c, k, r) = (33, 11, 11):该组中每个块共有 33 个码字,其中 11 个数据码, 11×2=22 个纠错码;

    第二组的属性:

    • 纠错块个数 = 2:该组中有两个块;
    • (c, k, r) = (34, 12, 11):该组中每个块共有 34 个码字,其中 12 个数据码, 11×2=22 个纠错码;

    具体示例如下表所示,且由于使用二进制会使得表格过大,故转为范围在 0~255 的十进制。其中组 1 的每个块,都有 11 个数据码, 22 个纠错码;组 2 的每个块,都有 12 个数据码,22 个纠错码。

    数据 每个块的纠错码
    1

    2
    67 85 70 134 87 38 85 194 119 50 6 

    66 7 118 134 242 7 38 86 22 198 199
    199 11 45 115 247 241 223 229 248 154 117 236 38 6 50 17 7 236 213 87 148 235 

    177 212 76 133 75 242 238 76 195 230 189 106 248 134 76 40 154 27 195 255 117 129
    2

    2
    247 119 50 7 118 134 87 38 82 6 134 151 

    194 6 151 50 16 236 17 236 17 236 17 236
    96 60 202 182 124 157 200 134 27 129 209 182 70 85 246 230 247 70 66 247 118 134

    173 24 147 59 33 106 40 255 172 82 2 157 242 33 229 200 238 106 248 134 76 40

    二维码的纠错码主要是通过里德-所罗门纠错算法(Reed-Solomon Error Correction)实现的。

    (关于 Reed-Solomon 算法,现在此处占坑,回头研究了再写上去)

    五. 最终编码

    此时得到了数据,但还不能开始画图,因为二维码还需要将数据码与纠错码的各个字节交替放置。

    5.1 穿插放置

    继续以第四章中给出的示例为例,给出其穿插放置的过程。

    5.1.1 数据码穿插放置

    第四章示例中的数据码如下表所示:

    块数                      
    块1 67 85 70 134 87 38 85 194 119 50 6
    块2 66 7 118 134 242 7 38 86 22 198 199
    块3 247 119 50 7 118 134 87 38 82 6 134
    块4 194 6 151 50 16 236 17 236 17 236 17

    提取每一列数据:

    • 第一列:67, 66, 247, 194;
    • 第二列:85, 7, 119, 6;
    • ……
    • 第十一列:6, 199, 134, 17;
    • 第十二列:151, 236;

    将上述十二列的数据拼在一起:67, 66, 247, 194, 85, 7, 119, 6,…, 6, 199, 134, 17, 151, 236。

    纠错码如下表所示:

    块数                      
    块1 199 11 45 115 247 241 223 229 248 154 117
    块2 177 212 76 133 75 242 238 76 195 230 189
    块3 96 60 202 182 124 157 200 134 27 129 209
    块4 173 24 147 59 33 106 40 255 172 82 2

    同样的方法,将 22 列数据放在一起:199, 177, 96, 173, 11, 212, 60, 24, …, 148, 117, 118, 76, 235, 129, 134, 40。

    上述部分即为二维码的数据区。

    5.2 剩余位 (Remainder Bits)

    对于某些 Version 的二维码,得到上面的数据区结果长度依旧不足,需要加上最后的剩余位。比如对于 Version 5 + H 纠错等级的二维码,剩余位需要加 7bits,即加 7 个 0。参看 QR Code Spec 的 Table-1 一表即可查询不同 Version 的剩余位信息,如下图 5.1 所示:
     
    图5.1 不同 Version 的剩余位 

     

    六. 二维码的绘制

    终于讲到二维码绘制过程了,绘制的过程按照顺序对图 1.1 中各个重要部分依次讲解。

    6.1 定位图案 (Position Detection Pattern)

    首先在二维码的三个角上绘制定位图案。定位图案与尺寸大小无关,一定是一个 7×7 的矩阵。如下图 6.1 所示:
     
    图6.1 定位图案 (Position Detection Pattern) 

     

    6.2 对齐图案 (Alignment Pattern)

    然后绘制对齐图案。对齐图案与尺寸大小无关,一定是一个 5×5 的矩阵。如下图 6.2 所示:
     
    图6.2 对齐图案 (Alignment Pattern) 

     

    对齐图案绘制的位置,可参看 QR Code Spec 的 Table-E.1 一表查询,部分内容如下图 6.3 所示:
     
    图6.3 对齐图案位置索引表(部分) 

     

    下图 6.4 是上述表格中 Version 8 的一个例子,对于 Version 8 的二维码,行列值在 6, 24, 42 的几个点都会有对齐图案。

     


     
    图6.4 对齐图案例程 1 

     

    下图 6.5 是最近我老妈怂恿我用支付宝抢红包时给我发来的二维码,该二维码中只有一个对齐图案, 故 Version 应在 V2——V6 之间。

     


     
    图6.5 对齐图案例程 2 

     

    6.3 时序图案 (Timing Pattern)

    时序图案是两条连接三个定位图案的线,如下图 6.6 所示: 
     
    图6.6 时序图案例程 1 

     

    依旧拿支付宝红包的二维码为例,其时序图案如图 6.7 所示:
     
    图6.7 时序图案例程 2 


    这里写图片描述

     

    6.4 格式信息

    格式信息如下图 6.8 所示: 
     
    图6.8 格式信息 

     

    格式信息在定位图案周围分布,由于定位图案个数固定为 3 个,且大小固定,故格式信息也是一个固定 15bits 的信息。每个 bit 的位置如下图 6.9 所示:(注:图中的 Dark Module 是固定永远出现的
     
    图6.9 格式信息位置 

     

    15bits 中数据,按照 5bits 的数据位 + 10bits 纠错位的顺序排列:

    • 数据位占 5bits:其中 2bits 用于表示使用的纠错等级 (Error Correction Level),3bits 用于表示使用的蒙版 (Mask) 类别;
    • 纠错位占 10bits:主要通过 BCH Code 计算;

    为了减少扫描后图像识别的困难,最后还需要将 15bits 与 101010000010010 做异或 XOR 操作。因为我们在原格式信息中可能存在太多的 0 值(如纠错级别为 00,蒙版 Mask 为 000),使得格式信息全部为白色,这将增加分析图像的困难。

    纠错等级的编码如下图 6.10 的表格所示:
     
    图6.10 纠错等级编码 

     

    关于蒙版图案的生成,在后文 6.7 中具体说明。格式信息的示例如下:

    假设存在纠错等级为 M(对应 00),蒙版图案对应 000,5bits 的数据位为 00101,10bits 的纠错位为 0011011100: 
    则生成了在异或操作之前的 bits 序列为:001010011011100 
     101010000010010 做异或 XOR 操作,即得到最终格式信息:100000011001110

    6.5 版本信息 (Version Information)

    对于 Version 7 及其以上的二维码,需要加入版本信息。如下图 6.11 蓝色部分所示:
     
    图6.11 版本信息 

     

    版本信息依附在定位图案周围,故大小固定为 18bits。水平竖直方向的填充方式如下图 6.12 所示:
     
    图6.12 版本信息填充方式 

     

    18bits 的版本信息中,前 6bits 为版本号 (Version Number),后 12bits 为纠错码 (BCH Bits)。示例如下:

    假设存在一个 Version 为 7 的二维码(对应 6bits 版本号为 000111),其纠错码为 110010010100; 
    则版本信息图案中的应填充的数据为:000111110010010100

    6.6 数据码与纠错码

    此后即可填充第五章得到的数据内容了。填充的思想如下图 6.13 的 Version 3 二维码所示,从二维码的右下角开始,沿着红线进行填充,遇到非数据区域,则绕开或跳过。

     


     
    图6.13 二维码数据填充(原始版) 

     

    然而这样难以理解,我们可以将其分为许多小模块,然后将许多小模块串连在一起,如下图 6.14 所示(截取自 QR Code Spec 的图 15):

    图6.14 二维码数据填充 

     

    小模块可以分为常规模块和非常规模块,每个模块的容量都为 8。常规情况下,小模块都为宽度为 2 的竖直小矩阵,按照方向将 8bits 的码字填充在内。非常规情况下,模块会产生变形。 
    填充方式上图 6.14,图中深色区域(如 D1 区域)填充数据码,白色区域(如 E15 区域)填充纠错码。遍历顺序依旧从最右下角的 D1 区域开始,按照蛇形方向(D1→D2→…→D28→E1→E2→…→E16→剩余码)进行小模块的填充,并从右向左交替着上下移动。下面给出若干填充原则:

    原则 1:无论数据的填充方向是向上还是向下,常规模块(即 8bits 数据全在两列内)的排列顺序应是从右向左,如下图 6.15所示;
     
    图6.15 常规模块内的填充方向 

     

    原则 2:每个码字的最高有效位(即第7个bit)应置于第一个可用位。对于向上填充的方向,最高有效位应该占据模块的右下角;向下填充的方向,最高有效位占据模块的右上方。 
    注:对于某些模块(以下图 6.17 为例),如果前一个模块在右边模块的列内部结束,则该模块成为不规则模块,且与常规模块相比,原本填充方向向上时,最高位应该在右上角,此时则变为左下角; 
    原则 3:当一个模块的两列同时遇到对齐图案或时序图案的水平边界时,它将继续在图案的上方或下方延续; 
    原则 4:当模块到达区域的上下边界(包括二维码的上下边界、格式信息、版本信息或分隔符)时,码字中任何剩余 bits 将填充在左边的下一列中,且填充方向反转;如下图 6.16 中的两个模块遇到了二维码的上边界,则方向发生变化;

     
    图6.16 非常规模块填充方向的改变(举例于 QR Code Spec 图 13) 

     

    原则 5:当模块的右一列遇到对齐图案,或遇到被版本信息占据的区域时,数据位会沿着对齐图案或版本信息旁边的一列继续填充,并形成一个不规则模块。如果当前模块填充结束之前,下一个的两列都可用,则下一个码字的最高有效位应该放在单列中,如下图 6.17 所示:
     
    图6.17 模块单列填充 

     

    6.7 蒙版图案

    按照上述思路即可将二维码填充完毕。但是那些点并不均衡,如果出现了大面积的空白或黑块,扫描识别会十分困难,所以按照在前文 6.4 中格式信息的处理思路,对整个图像与蒙版进行蒙版操作(Masking),蒙版操作即为异或 XOR 操作。 
    二维码又 8 种蒙版可以使用,如下图 6.18 所示,公式也在图中说明。蒙版只会和数据区进行异或操作,不会影响与格式信息相关的功能区。 
    注:选择一个合适的蒙版也是有一定算法的。

    蒙版图案如下图 6.18 所示,对应的产生公式与蒙版 ID 如下图 6.19 的表格所示:
     
    图6.18 蒙版图案 


     
    图6.19 蒙版图案产生公式

     

    蒙版操作的过程与对比图如下图 6.20 所示,图中最上层是没有经过蒙版操作的原始二维码,其中存在大量黑色区域,难以后续的分析识别。经过两种不同蒙版的处理,可以看到最后生成的二维码变的更加混乱,容易识别。 
     
    图6.20 蒙版操作示例 

     

    蒙版操作之后,得到的二维码即为最终我们平常看到的结果。

    七. 源码

    笔者原本准备用 C++ 与 OpenCV 写一个二维码解析程序,现在学了二维码的原理后,发现好难。另外网上关于二维码解析与生成的程序基本都是用 Python 写的,笔者又想找个合适机会学习一下 Python,所以这段时间就准备从二维码入手,学习一下 Python 的基础~

    源码及解析笔者会随学习的进度持续更新~

    八. 后记

    笔者学习完毕二维码内容后不禁感叹,二维码规则的制定当真是凝聚了多少研究者的心血。学无止境,在知识的海洋中,当真是需要抱着敬畏之心和谦卑的态度,才能体会到这片海洋的浩瀚。 
    研究二维码的过程十分有趣,学到了不少东西,后续过程中笔者会持续更新对二维码的学习心得体会~

     

    展开全文
  • 二维码生成

    2020-09-13 17:19:13
    二维码生成 开发环境:jdk8 springboot: 2.3.3.RELEASE 1.引入相应的jar包 <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>...
  • C# 二维码生成 ( QRCoder )

    万次阅读 2018-07-18 00:43:57
    二维码 1.前言 seaconch 最近在搞二维码方面的一些东西,所以接触了一些二维码相关,那么既然用过了就要有用过了的样子 其实关于二维码的文章真的多的数不胜数,有很多写的很认真,很好,但这就像是学习一样,...
  • Android生成自定义二维码

    万次阅读 多人点赞 2019-11-13 10:20:38
    前面说过两种二维码扫描方式,现在说二维码生成,使用Google开源库Zxing,项目地址:https://github.com/ZBar/ZBar,我们只需要里面的jar包:core:x.x.x.jar,建议用core:3.3.0。 1.引入jar包 app build....
  • Java实现二维码生成 Google-Zxing

    万次阅读 多人点赞 2020-06-23 17:24:49
    本篇文章将介绍java中如何生成二维码二维码的展示主要包括两各方面:1.直接生成图片(直接生成图片不需要web程序,maven工程即可) 2.将二维码转为字节数组,然后在web页面显示。web项目的目录结构以前面的一篇...
  • 什么是二维码 二维码 (2-dimensional bar code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的。 在许多种类的二维条码中,常用的码制有:Data Matrix, Maxi ...
  • 二维码生成器和二维码扫描器

    千次阅读 2016-07-13 00:14:41
    二维码生成器二维码扫描 一)二维码生成器 下载demo: 1.导入库文件( libqrencode)  配置:开启这个HAVE_CONFIG_H宏定义 如下图  build settings--> Preprocessor Macros ->添加 “HAVE_CONFIG...
  • 在线二维码生成技术

    千次阅读 2018-12-21 17:09:44
    注:本文用以解决实际生产需求,而非深入学习研究所用,如需深入请接入:QR Code API 一、引入pom依赖 &lt;dependency&gt; &lt;groupId&gt;com.google.zxing&...${go...
  • 上面一篇文章说到了用 js 实现二维码生成,下面来说说在后台生成,前端展示的方式。 引入 jar 包 &amp;amp;lt;!-- 条形码、二维码生成 --&amp;amp;gt; &amp;amp;lt;dependency&amp;amp;gt; &...
  • 1. 使用github上C++二维码生成程序源码在Qt5.5.1(QWidget)上实现的二维码生成程序源码。 (github源码网址https://github.com/Hackaroth/QRCODE) 2. 二维码生成源码部分修改了一些使用Qt运行出现的问题及一些代码错误...
  • 现在的互联网时代,二维码处处可见,这次我们研究下二维码生成插件qrious 二维码百科: 二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比...
  • 渠道二维码生成与统计,通过公众号接口开发的功能,功能用于统计粉丝来源关注,记录每个粉丝的关注和取关,从哪个渠道而来。可以自己根据公众号接口开发实现功能效果,也可以直接用微号帮平台渠道二维码生成。 1、...
  • 【微信小程序】二维码生成与识别

    万次阅读 2017-06-09 11:49:59
    title: 【微信小程序】二维码生成与识别器 type: categories date: 2017-03-10 09:34:00 categories: 微信小程序tags: [二维码生成,二维码识别] 一个二维码生成与识别的很简单的微信小程序,主要是为了走一下小...
  • PHP 二维码生成 QRCODE生成 源码

    热门讨论 2020-07-30 23:32:48
    PHP二维码生成源码 QRCODE生成源码 PHP二维码生成软件 PHP二维码生成系统 PHP 二维码
  • 二维码生成工具 无广告 二维码生成工具 无广告 二维码生成工具 无广告
  • java二维码生成技术

    2019-06-27 18:11:20
    java二维码生成技术 **  自从微信扫描出世,二维码扫描逐渐已经成为一种主流的信息传递和交换方式。下面就介绍一下我学习到的这种二维码生成方式。预计再过不久身份证户口本等都会使用二维码识别了,今天就做一个...
1 2 3 4 5 ... 20
收藏数 76,546
精华内容 30,618
关键字:

二维码生成