码迷,mamicode.com
首页 > 编程语言 > 详细

二维码的C语言实现

时间:2015-03-07 14:19:09      阅读:480      评论:0      收藏:0      [点我收藏+]

标签:

二维码在今天已经相当普及了,制作二维码也不难,网上有很多制作二维码的网站,输入信息,立即转换出二维码。然而我们要自己根据信息制作出二维码却不那么简单。网上粗略找了下源码,几乎清一色的是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

void Disp_FixelPic(int iPenX,intiPenY,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);

                                    

                            }

                   }

                  

         }

}

二维码的C语言实现

标签:

原文地址:http://blog.csdn.net/osanwenyu/article/details/44114779

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!