二维码的C语言实现

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


一、初识二维码

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

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

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

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

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

二维码的C语言实现_第1张图片

草料二维码:你好


二维码的C语言实现_第2张图片

联图网二维码:你好


二维码的C语言实现_第3张图片

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


二、移植准备:

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文件添加进来。


二维码的C语言实现_第4张图片



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函数中添加最重要的两句二维码库调用


二维码的C语言实现_第5张图片

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

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

 

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进行描点

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;iiHeight;i++)
	{
		for(j=0;jiWidth;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

你可能感兴趣的:(二维码的C语言实现)