【数字图像处理】基于qrencode的二维码生成C语言实现

文章目录

(一)关于QR二维码

一:什么是二维码

二维码 (2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上) 分布的黑白相间的图形记录数据符号信息的。 在许多种类的二维条码中,常用的码制有:Data Matrix, Maxi Code, Aztec, QR Code, Vericode, PDF417, Ultracode, Code 49, Code 16K等。
1.堆叠式/行排式二维条码,如,Code 16K、Code 49、PDF417
2.矩阵式二维码,最流行莫过于QR CODE 二维码的名称是相对与一维码来说的,比如以前的条形码就是一个“一维码”,它的优点有:二维码存储的数据量更大;可以包含数字、字符,及中文文本等混合内容;有一定的容错性(在部分损坏以后可以正常读取);空间利用率高等。

二:什么是QR二维码

QR(Quick-Response) code是被广泛使用的一种二维码,解码速度快。 由DENSO(日本电装)公司开发,由JIS和ISO将其标准化。
QR码呈正方形,只有黑白两色。在3个角落,印有较小,像「回」字的的正方图案。这三个是帮助解码软件定位的图案,使用者不需要对准,无论以任何角度拍摄,内容仍可正确被读取。
【数字图像处理】基于qrencode的二维码生成C语言实现

三:将数据编码成QR码的流程

数据分析:确定编码的字符类型,按相应的字符集转换成符号字符; 选择纠错等级,在规格一定的条件下,纠错等级越高其真实数据的容量越小。
数据编码:将数据字符转换为位流,每8位一个码字,整体构成一个数据的码字序列。其实知道这个数据码字序列就知道了二维码的数据内容。
【数字图像处理】基于qrencode的二维码生成C语言实现

【数字图像处理】基于qrencode的二维码生成C语言实现

数据可以按照一种模式进行编码,以便进行更高效的解码,例如:对数据:01234567编码(版本1-H), 1)分组:012 345 67 2)转成二进制:012→0000001100 345→0101011001 67 →1000011 3)转成序列:0000001100 0101011001 1000011 4)字符数 转成二进制:8→0000001000 5)加入模式指示符(上图数字)0001:0001 0000001000 0000001100 0101011001 1000011 对于字母、中文、日文等只是分组的方式、模式等内容有所区别。基本方法是一致的
纠错编码:按需要将上面的码字序列分块,并根据纠错等级和分块的码字,产生纠错码字,并把纠错码字加入到数据码字序列后面,成为一个新的序列。

【数字图像处理】基于qrencode的二维码生成C语言实现

在二维码规格和纠错等级确定的情况下,其实它所能容纳的码字总数和纠错码字数也就确定了,比如:版本10,纠错等级时H时,总共能容纳346个码字,其中224个纠错码字。 就是说二维码区域中大约1/3的码字时冗余的。对于这224个纠错码字,它能够纠正112个替代错误(如黑白颠倒)或者224个据读错误(无法读到或者无法译码), 这样纠错容量为:112/346=32.4%
构造最终数据信息:在规格确定的条件下,将上面产生的序列按次序放如分块中 按规定把数据分块,然后对每一块进行计算,得出相应的纠错码字区块,把纠错码字区块 按顺序构成一个序列,添加到原先的数据码字序列后面。 如:D1, D12, D23, D35, D2, D13, D24, D36, … D11, D22, D33, D45, D34, D46, E1, E23,E45, E67, E2, E24, E46, E68,…
构造矩阵:将探测图形、分隔符、定位图形、校正图形和码字模块放入矩阵中。
把上面的完整序列填充到相应规格的二维码矩阵的区域中
掩摸:将掩摸图形用于符号的编码区域,使得二维码图形中的深色和浅色(黑色和白色)区域能够比率最优的分布。 一个算法,不研究了,有兴趣的同学可以继续。
格式和版本信息:生成格式和版本信息放入相应区域内。 版本7-40都包含了版本信息,没有版本信息的全为0。二维码上两个位置包含了版本信息,它们是冗余的。 版本信息共18位,6X3的矩阵,其中6位时数据为,如版本号8,数据位的信息时 001000,后面的12位是纠错位。

【数字图像处理】基于qrencode的二维码生成C语言实现

(二)编译QRencode

libqrencode 可以使用cmake 进行编译
Linux:

cmake ..
make

Windows:

cmake .. -G "MinGW Makefiles"
mingw32-make.exe

(三)使用libqrencode.a

/*
 * @Descripttion: 二维码编码
 * @version: V 1.0
 * @Author: Yueyang
 * @email: 1700695611@qq.com
 * @Date: 2020-11-26 11:43:15
 * @LastEditors: Yueyang
 * @LastEditTime: 2020-11-26 18:01:26
 */
#include <string.h>
#include "qrencode.h"  
#include "cv.h"
#include "li_image.h"
#include "li_qrcode.h"

/**
 * @name: Li_QREncode
 * @msg: 二维码生成
 * @param {BYTE* src字符串}
 * @return {Li_Image*}
 */
Li_Image* Li_QREncode(BYTE* src)
{
    QRcode*  pQRC;
    int unWidth, unWidthAdjusted, unDataBytes;
    Li_Image* out;
    BYTE* pSourceData,*pDestData,*pRGBData ;
    if (pQRC = QRcode_encodeString(src, 0, QR_ECLEVEL_H, QR_MODE_8, 1))
    {
        unWidth=pQRC->width;
                unWidthAdjusted = unWidth * 8 * 3;
        if (unWidthAdjusted % 4)
            unWidthAdjusted = (unWidthAdjusted / 4 + 1) * 4;
        unDataBytes = unWidthAdjusted * unWidth * 8;
        out=Li_Create_Image(8*unWidth,8*unWidth,LI_DEP_24U,LI_BMP_888);
        pSourceData = pQRC->data;
        pRGBData=out->data;
        pSourceData = pQRC->data;
        for (int y = 0; y < unWidth; y++)
        {
            pDestData = pRGBData + unWidthAdjusted * y * 8;
            for (int x = 0; x < unWidth; x++)
            {
                if (*pSourceData & 1)
                {
                    for (int l = 0; l < 8; l++)
                    {
                        for (int n = 0; n < 8; n++)
 
                        {
                             //以下三行是设置三基色,三基色都设置为0x00,则生成的二维码图片就是黑色的了,要什么颜色自己调整
                            *(pDestData + n * 3 + unWidthAdjusted * l) = 0x00;            
                            *(pDestData + 1 + n * 3 + unWidthAdjusted * l) = 0x00;
                            *(pDestData + 2 + n * 3 + unWidthAdjusted * l) = 0x00;
                        }
                    }
                }
                pDestData += 3 * 8;
                pSourceData++;
            }
        }
    }
    return out;
}


/*
 * @Descripttion: 
 * @version: 
 * @Author: Yueyang
 * @email: 1700695611@qq.com
 * @Date: 2020-11-26 12:23:49
 * @LastEditors: Yueyang
 * @LastEditTime: 2020-11-26 15:04:58
 */
#include "cv.h"
#include "li_image.h"
#include "li_qrcode.h"

int main()
{
    Li_Image* Qr=Li_QREncode("123.57.93.3");
    Li_Save_Image("QR.bmp",Qr);
    
    LILOG("OVER");
}

(四)效果

【数字图像处理】基于qrencode的二维码生成C语言实现

(五)写在后面

代码中有错误的地方还望指出。我已经将项目同步到了github,我会实时更新这个代码仓库。
项目github地址:
LiteCV

上一篇:[LOJ]#2831. 「JOISC 2018 Day 1」道路建设 LCT+树状数组


下一篇:使用ABAP创建QR Code(二维码)