二维码的C语言实现

来源:互联网 发布:李敖 知乎 编辑:程序博客网 时间:2024/06/02 00:15

二维码在今天已经相当普及了,制作二维码也不难,网上有很多制作二维码的网站,输入信息,立即转换出二维码。然而我们要自己根据信息制作出二维码却不那么简单。网上粗略找了下源码,几乎清一色的是java/c#版本的,这对于stm32芯片项目来说没什么大帮助。最终辗转找到Linux上的qrencode软件包,将其移植了过来。


一、初识二维码

a)        二维码可以存储1850个字节的信息,可以存数字、字母、汉子、图像

b)        二维码三个矩形用于定位,矩形样式可以更改,整张图片甚至可以倒转过来

c)        拥有冗余信息,根据容错率可以选择最多50%

d)        因为冗余的关系,二维码中间以及右下角可以放置图案

f)         二维码的算法根据容错率的不同会产生不同的图案


草料二维码:你好


联图网二维码:你好



很显然两个网站的算法是不同的,但包含的信息都一样。用任意扫描端都能扫描出其中的内容


二、移植准备:

a) qrencode-3.4.4.tar.gz作为移植源码 百度盘:http://pan.baidu.com/s/1ntyvf7r

b) stm32f429i-discovery探索板

c) 移植好stemwin的例程 详见官方例程STM32Cube_FW_F4_V1.4.0目录下的\Projects\STM32F429I-Discovery\Applications\STemWin


三、移植过程

a)        用iar打开带stemwin的工程。 新建qrcode工程子目录,并将所有qrencode.tar.gz解压后的.c文件添加进来。




b)     在windows文件夹中打开此工程目录STM32Cube_FW_F4_V1.4.0\Projects\STM32F429I-Discovery\Applications\STemWin\qrcode

复制所有qrencode.tar.gz解压后的.c文件到src文件夹中

复制所有qrencode.tar.gz解压后的.h文件到inc文件夹中

 

c)        先保存编译一下。报了一大堆错,这是肯定的,源码包用的是linux的LCD库文件,解决方法是在这里将报错的都注释掉就可以了

在main函数中添加最重要的两句二维码库调用


Qrcode中就包含着我们最终需要的二维码信息,其实就是一个图,存着01比特信息

 调用fb_qrdisp显示此二维码,这里贴出fb_qrdisp源码,注释掉的是已经修改的部分

 

<pre name="code" class="cpp">int Fb_QrDisp(int iPenX,int iPenY,QRcode*pQRcode){         T_PixelDatasg_tOriginPixelDatas;         T_PixelDatasg_tZoomPixelDatas;         //intiZoom;         inti;                  g_tOriginPixelDatas.iWidth= pQRcode->width;         g_tOriginPixelDatas.iHeight=pQRcode->width;         g_tOriginPixelDatas.iLineBytes=g_tOriginPixelDatas.iWidth;         g_tOriginPixelDatas.aucPixelDatas= pQRcode->data;/*   if(pQRcode->version <= 1)    {                   iZoom= 2;    }         else         {                   iZoom= 2;          }   g_tZoomPixelDatas.iWidth = pQRcode->width*iZoom;         g_tZoomPixelDatas.iHeight=pQRcode->width*iZoom;         g_tZoomPixelDatas.iLineBytes=g_tZoomPixelDatas.iWidth;         g_tZoomPixelDatas.aucPixelDatas= malloc(g_tZoomPixelDatas.iWidth*\                                                         g_tZoomPixelDatas.iHeight);          if(g_tZoomPixelDatas.aucPixelDatas== NULL)         {                   printf("g_tZoomPixelDatas->aucPixelDatasmalloc failed\n");                   return-1;         }          PicZoom(&g_tOriginPixelDatas,&g_tZoomPixelDatas);#if 0         printf("g_tZoomPixelDatas.iWidth=%d,g_tZoomPixelDatas.iHeight=%d\n",\               g_tZoomPixelDatas.iWidth,g_tZoomPixelDatas.iHeight);  for(i=0;i<(g_tZoomPixelDatas.iWidth*g_tZoomPixelDatas.iHeight);i++){         printf("0x%x,",g_tZoomPixelDatas.aucPixelDatas[i]);}printf("\n"); #endif*/         Disp_FixelPic(iPenX,iPenY,&g_tZoomPixelDatas);return 0;  }


因为stmf429运行起来后内存不够,这里不用申请内存再扩充放大二维码数据的方法,而是直接描点。所以这里注释掉了放大部分

e)        紧接着调用Disp_FixelPic根据qrcode进行描点

</pre><pre name="code" class="cpp"><pre name="code" class="cpp">void Disp_FixelPic(int iPenX,int iPenY,PT_PixelDatas ptPixelDatas){    int i=0,j=0;        GUI_SetBkColor(GUI_WHITE);        GUI_Clear();            GUI_SetPenSize(1);for(i=0;i<ptPixelDatas->iHeight;i++){for(j=0;j<ptPixelDatas->iWidth;j++){if(ptPixelDatas->aucPixelDatas[i*ptPixelDatas->iHeight+j]&0x01){//lcd_pixel_show(j+iPenX, i+iPenY,0x00);                              GUI_SetColor(GUI_BLACK);                                 GUI_FillRect(j*8+iPenX, i*8+iPenY,j*8+8+iPenX, i*8+8+iPenY);}else{                              GUI_SetColor(GUI_WHITE);  //lcd_pixel_show(j+iPenX, i+iPenY, 0xffffff);                              //GUI_DrawPoint(j*8+iPenX, i*8+iPenY);                              GUI_FillRect(j*8+iPenX, i*8+iPenY,j*8+8+iPenX, i*8+8+iPenY);}}}}

这里注释掉了原lcd描点函数,而是采用了stemwin提供的矩形填充函数

f)         编译运行,能看到LCD显示出二维码。至此移植完毕

 

 

移植过程中有一个小问题,因为调用了stemwin的画笔函数,当画笔GUI_SetPenSize(1);的时候,描的是一个点,当GUI_SetPenSize(16);的时候,画的是一个大圆点,而不是一个方点,这里要注意一下不能采用此画笔,而要采用矩形填充函数GUI_FillRect

1 1