把24位bmp位图按水平扫描和垂直扫描转为点阵数组

本文介绍了一个将24位BMP图像转换为适用于嵌入式系统的点阵数组的方法,包括水平扫描和垂直扫描两种方式。通过C语言程序实现,详细展示了如何解析BMP文件并将其转化为易于嵌入式设备显示的点阵数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

把24位bmp位图按水平扫描和垂直扫描转为点阵数组


 本来朋友有一个移动和联通的logo点阵,现在突然需要电信的logo,所以就跟他要来了,移动和电信的logo数据,试着显示出来,其实也就是每个字节有8个点,1为显示的点,0不显示!麻烦的就是有要水平扫描和垂直扫描!

      所以就写了下面的程序,这个程序是未成品,我只弄了40*40的位图,而且是24位的bmp图片,其它的只要查看一下bmp文件格式,很容易就可以修改了!(生成的数据在文件里)

      有兴趣你也可以试一下!

 

 

恢复样子:

 

电信logo文件:放在和程序的目录下(文件被我改后辍了,不然不能上传,把后面的“.jpg”去掉就好了)

 

代码入下:

[c-sharp]  view plain copy
  1. #include "stdio.h"  
  2. #include "stdlib.h"  
  3. // 数据表 水平扫描  
  4. const unsigned char unicomLogo[] =                    
  5. {  
  6.         56,41,  
  7.       0x00,0x00,0x0C,0x00,0x60,0x00,0x00,0x00,0x00,0x7F,0x81,0xFC,0x00,0x00,0x00,0x00,  
  8.       0xFF,0xC3,0xFE,0x00,0x00,0x00,0x01,0xFF,0xE7,0xFF,0x00,0x00,0x00,0x01,0xF3,0xFF,  
  9.       0xCF,0x00,0x00,0x00,0x03,0xE1,0xFF,0x07,0x80,0x00,0x00,0x03,0xC0,0xFE,0x07,0x80,  
  10.       0x00,0x00,0x03,0xC0,0xFE,0x07,0x80,0x00,0x00,0x03,0xE1,0xFF,0x0F,0x80,0x00,0x00,  
  11.       0x01,0xF3,0xFF,0x9F,0x00,0x00,0x00,0x01,0xF9,0xEF,0x3F,0x00,0x00,0x00,0x00,0xFC,  
  12.       0xC6,0x7E,0x00,0x00,0x00,0x00,0x7E,0x00,0xFC,0x00,0x00,0x00,0x00,0x3F,0x01,0xF8,  
  13.       0x00,0x00,0x07,0xC0,0x1F,0x83,0xF0,0x07,0xC0,0x1F,0xF0,0xCF,0xC7,0xE6,0x0F,0xF0,  
  14.       0x3F,0xF9,0xE7,0xE7,0xCF,0x3F,0xF8,0x3F,0xFF,0xF3,0xFF,0x9F,0xFF,0xFC,0x7C,0x7F,  
  15.       0xE1,0xFF,0x0F,0xFC,0x7C,0x78,0x1F,0xC0,0x7E,0x07,0xF8,0x3C,0x78,0x1F,0x80,0xFE,  
  16.       0x03,0xF0,0x3C,0x78,0x3F,0xC0,0xFF,0x07,0xFC,0x3C,0x7C,0xFF,0xE1,0xFF,0x8F,0xFE,  
  17.       0x7C,0x3F,0xFD,0xF3,0xEF,0xCF,0xBF,0xF8,0x1F,0xF0,0xE7,0xC7,0xE7,0x1F,0xF0,0x0F,  
  18.       0xE0,0x4F,0x83,0xF2,0x0F,0xF0,0x03,0x80,0x1F,0x01,0xF0,0x03,0xC0,0x00,0x00,0x3E,  
  19.       0x00,0xFC,0x00,0x00,0x00,0x00,0x7C,0xC6,0x7C,0x00,0x00,0x00,0x00,0xF8,0xC6,0x3E,  
  20.       0x00,0x00,0x00,0x01,0xF3,0xFF,0x9F,0x00,0x00,0x00,0x01,0xF3,0xFF,0x8F,0x00,0x00,  
  21.       0x00,0x03,0xE0,0xFE,0x0F,0x80,0x00,0x00,0x03,0xE0,0xFE,0x07,0x80,0x00,0x00,0x03,  
  22.       0xE1,0xFF,0x07,0x80,0x00,0x00,0x03,0xF1,0xFF,0x8F,0x80,0x00,0x00,0x01,0xFF,0xEF,  
  23.       0xFF,0x00,0x00,0x00,0x00,0xFF,0xC7,0xFF,0x00,0x00,0x00,0x00,0x7F,0x83,0xFC,0x00,  
  24.       0x00,0x00,0x00,0x1F,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  
  25. };  
  26.   
  27. // 数据表 垂直扫描  
  28. const unsigned char cmccLogo[] =  
  29. {  
  30.     48,40,  
  31.     0x00,0x00,0xff,0x00,0x00,0x00,0x00,0xe0,0xff,0x07,0x00,0x00,0x00,0xf8,0xff,0x1f,  
  32.     0x00,0x00,0x00,0xfe,0xff,0x7f,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0xc0,0x3f,  
  33.     0x63,0xfc,0x01,0x00,0xc0,0x1f,0xe7,0xf8,0x03,0x00,0xe0,0x0f,0xce,0xf1,0x07,0x00,  
  34.     0xf0,0x07,0x9c,0xf1,0x0f,0x00,0xf8,0x07,0x39,0xe3,0x0f,0x00,0xf8,0x83,0x71,0xc6,  
  35.     0x1f,0x00,0xfc,0xc1,0x71,0x8e,0x3f,0x00,0xfc,0xe0,0xe1,0x1c,0x3f,0x00,0x7e,0xf0,  
  36.     0xc0,0x19,0x3f,0x00,0x3e,0x70,0x98,0x33,0x7e,0x00,0x3e,0x38,0x98,0x73,0x7c,0x00,  
  37.     0x1f,0x1c,0x0c,0xe3,0x78,0x00,0x0f,0x0e,0x06,0xe3,0x78,0x00,0x0f,0x07,0x87,0xe1,  
  38.     0x70,0x00,0x0f,0x87,0xc1,0xe1,0x70,0x00,0x8f,0xc3,0xe1,0x70,0x70,0x00,0x8f,0xc3,  
  39.     0x70,0x38,0x78,0x00,0x8f,0x63,0x30,0x38,0x78,0x00,0x1e,0xe7,0x18,0x1c,0x7c,0x00,  
  40.     0x3e,0xe7,0x0c,0x0e,0x7e,0x00,0x3e,0xce,0x01,0x07,0x3f,0x00,0x7c,0x9c,0x81,0x03,  
  41.     0x3f,0x00,0xfc,0x98,0xc3,0x81,0x3f,0x00,0xfc,0x31,0xe7,0xc1,0x1f,0x00,0xf8,0x71,  
  42.     0xce,0xe0,0x1f,0x00,0xf0,0xe3,0x1c,0xf0,0x0f,0x00,0xf0,0xc7,0x39,0xf8,0x07,0x00,  
  43.     0xe0,0x8f,0x31,0xf8,0x07,0x00,0xc0,0x1f,0x63,0xfc,0x03,0x00,0x80,0x3f,0xe7,0xfe,  
  44.     0x01,0x00,0x00,0xff,0xff,0x7f,0x00,0x00,0x00,0xfc,0xff,0x3f,0x00,0x00,0x00,0xf0,  
  45.     0xff,0x0f,0x00,0x00,0x00,0x80,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  
  46. };  
  47.  
  48.  
  49.  
  50.  
  51. #define MAX_BACK_COLOR 180  //颜色值  
  52. #define BMP_W_H        40   //准备转换的颜色的大小,也可以弄动态获取,但最近有点忙就不加上了  
  53. #define BUF_MAX_SIZE   10000  
  54. unsigned char bmpinf[BUF_MAX_SIZE];//保存整张图片,按16进制读取  
  55.   
  56. int bmp_data_start = 0;  //图像的数据偏移位置,bmp的第10位开始,一共4位,低位在前,可参考bmp文件格式说明  
  57.   
  58. int bmpInfLen = 0;      //bmpinf数组已用空间  
  59.   
  60. //画水平logo的  
  61. int hexLogView_horizontal(const unsigned char loghex[],int size)  
  62. {  
  63.     int w,h,pos,i,j;  
  64.   
  65.     if(loghex ==NULL)  
  66.         return 1;  
  67.     //获取宽高  
  68.     w = loghex[0]/8;  
  69.     h = loghex[1];  
  70.   
  71.     printf("/nsize of logo  =  %d/n",size);  
  72.     printf("logo view: /n/t");  
  73.   
  74.     //从第三个开始,前两个为宽高  
  75.     pos = 2;  
  76.   
  77.     //打印logo  
  78.     while(pos < size)//查到是否还有数据  
  79.     {  
  80.         for(i = 0; i < w; i++)//这个宽为数据高,(因为一个数据有8位)  
  81.         {  
  82.             for(j = 7; j >0; j--)//数据,高位在左,所以从第8位(最高位)开始  
  83.             {  
  84.                 if((loghex[pos+i]>>j)&0x1)//计算数据位置  
  85.                     printf("%c",64);//为1时,画@  
  86.                 else  
  87.                     printf("%c",32);//为0时,空格  
  88.             }  
  89.         }  
  90.         printf("/n/t");   
  91.         pos +=w;//下一行  
  92.     }  
  93.   
  94.     return 0;  
  95. }  
  96.   
  97. int hexLogView_vertical(const unsigned char loghex[],int size)  
  98. {  
  99.     int w,h,pos,i,j,k;  
  100.     if(loghex ==NULL)  
  101.         return 1;  
  102.   
  103.     //获取宽高  
  104.     w = loghex[0]/8;  
  105.     h = loghex[1];  
  106.   
  107.     printf("/nsize of logo  =  %d/n",size);  
  108.     printf("logo view: /n/t");  
  109.   
  110.     //从第三个开始,前两个为宽高  
  111.     pos = 2;  
  112.     //这里的数据第一行实际上是第一列  
  113.     //而我们无法按一列一列来画,所以我们选择先每一列的第一个,然后第二个。。。  
  114.     for(j = 0; j < w; j++)//每一列(这里把8位数据做为一大列)  
  115.     {  
  116.         for(k = 0 ; k < 8;k ++)//每一位  
  117.         {  
  118.             for(i = 0; i < h; i++)//每一行  
  119.             {  
  120.                 //printf("%d-%d,",pos+j+5*i,k);  
  121.                 if( (loghex[pos+ j + w*i]>>k) & 0x01)//计算数据位置  
  122.                         printf("%c",64);//为1时,画@  
  123.                     else  
  124.                         printf("%c",32);//为0时,空格  
  125.                   
  126.             }  
  127.             printf("/n/t");  
  128.         }  
  129.     }  
  130.     printf("/n");  
  131.     return 0;  
  132. }  
  133.   
  134. //把bmp的所有数据按16进制读出来  
  135. int bmpTohex(char *in_file, char * out_file,unsigned char bmpinf[])  
  136. {  
  137.     int ch,i = 0,j = 0;  
  138.     FILE * fi,*fo;  
  139.     //打开文件  
  140.     fi = fopen(in_file,"r");  
  141.     fo = fopen(out_file,"w+");  
  142.     if(fi == NULL ||fo == NULL)  
  143.     {  
  144.         printf("can't open file !/n");  
  145.         exit(1);  
  146.     }  
  147.     fprintf(fo,"const unsigned char logoInfHex =/n{/n/t");  
  148.   
  149.     //一直读取,直到bmp文件结束(EOF)  
  150.     //注意,在我读取时,有时16进制为“1A”时会被读成EOF,所以我用UltraEdit把“0A”改成了“0B”  
  151.     while((ch = fgetc(fi)) != EOF)  
  152.     {  
  153.           
  154.         fprintf(fo,"0x%02x,",ch);  
  155.   
  156.         bmpinf[j] =ch;//把图像同时保存在全局变量里  
  157.   
  158.         i++;  
  159.         if(i == 16)//输出到文件时,16个数据为一行  
  160.         {  
  161.             fprintf(fo,"/n/t");  
  162.             i = 0;  
  163.         }  
  164.         j++;  
  165.     }  
  166.     fprintf(fo,"/n};");  
  167.     printf("bmp size : %d",j);  
  168.     return j;//返回数据长度  
  169. }  
  170.   
  171. //把bmp文件数据转换成数组,分别在hexLogo_horizontal.txt和hexLogo_vertical.txt两个文件中  
  172. //一个是水平扫描,一个垂直扫描  
  173. void bmpInfToArray(char bmpInf[])  
  174. {  
  175.     int i,j,k,a;  
  176.     char tmp[BUF_MAX_SIZE];  
  177.     char bmp[BMP_W_H][BMP_W_H];  
  178.     FILE *fo,*fo4;  
  179.     fo =  fopen("hexLogo_horizontal.txt","w+");  
  180.     fo4 =  fopen("hexLogo_vertical.txt","w+");  
  181.   
  182.     fprintf(fo,"/*hexLogo_horizontal*//n");  
  183.     fprintf(fo,"const unsigned char horizontal_logo[] =/n{/n/t %d,%d,/n/t",BMP_W_H,BMP_W_H);  
  184.   
  185.     fprintf(fo4,"/*hexLogo_vertical*//n");  
  186.     fprintf(fo4,"const unsigned char vertical_logo[] =/n{/n/t %d,%d,/n/t",BMP_W_H,BMP_W_H);  
  187.   
  188.     //计算偏移量,偏移量后面就是图像的具体数据  
  189.     //bmp的格式太多,我这里用的是24位时的,其它的可以参考相关资料修改,不难  
  190.     bmp_data_start = (bmpinf[13]<<24) + (bmpinf[12]<<16) +(bmpinf[11]<<8) + bmpinf[10];  
  191.   
  192.     k = -1;//数据到单色数组  
  193.     for(i = bmp_data_start;i < bmpInfLen;)  
  194.     {  
  195.         k++;  
  196.         tmp[k] = 0;//默认为0,无色块  
  197.         for(j =0; j < 3; j++)  
  198.             {  
  199.                 a = i+j;  
  200.                 if(bmpinf[a] < MAX_BACK_COLOR)//只要有任意一个颜色值小于MAX_BACK_COLOR,就把它当然有颜色的,(因为3个都为255时是白色)  
  201.                 {  
  202.                     tmp[k] = 1; //                
  203.                 }  
  204.             }  
  205.         i += 3;//24位时,3个字节(3原色)为一个点  
  206.         //bmp是按行存储的,并且是行序是倒过来的  
  207.         //还有一点就是因为bmp每一行都要求是4的整数倍,所以其实图像大小时要记得做相关处理(我选取40*40,列数是40,无须处理)  
  208.         //举个例子 ,3*3的位图  
  209.         //每一行不是3*3字节,面是有4*3个字节,最后的3字节是无用的!  
  210.     }  
  211.   
  212.     a = 0;  
  213.     k = 0;  
  214.     //水平扫描数据输出  
  215.     //因为行序是倒序,所以我们倒着转存  
  216.     for (i = BMP_W_H -1; i >= 0 ; i--)  
  217.     {  
  218.         for(j = 0 ; j < BMP_W_H; j++)  
  219.         {  
  220.             a = a*2 | tmp[i*40+j];//每8位为一个数据  
  221.             k++;  
  222.             if((j+1)% 8 == 0)//每8位为一个数据  
  223.             {  
  224.                 fprintf(fo,"0x%02x,",a);a = 0;k = 0;//输出数据  
  225.             }  
  226.         }  
  227.         if(i%2 == 0)  
  228.             fprintf(fo,"/n/t");  
  229.     }  
  230.     fprintf(fo,"/n};");  
  231.   
  232.     //在这里先把图像,下面就比较文便处理了  
  233.     for(i = 0; i < BMP_W_H; i++)  
  234.         for(j = 0; j < BMP_W_H; j++)  
  235.         {  
  236.             bmp[i][j] = 0;  
  237.             if(i > 1)  
  238.             {  
  239.                 bmp[i][j] = tmp[(BMP_W_H -1 - i)*40+j];//下上反转过来  
  240.             }  
  241.         }  
  242.       
  243.     //垂直扫描数据输出  
  244.     for (j = 0,a = 0; j < BMP_W_H; j++) //按列来保存  
  245.     {  
  246.         for(i = 0 ; i < BMP_W_H/8; i++)//每一列的的每个数据(8位)  
  247.         {  
  248.   
  249.             a = a*2 | bmp[i*8 +7][j];//这里是高位在下(如果高位在中的话0到7倒置就好了)  
  250.             a = a*2 | bmp[i*8 +6][j];  
  251.             a = a*2 | bmp[i*8 +5][j];  
  252.             a = a*2 | bmp[i*8 +4][j];  
  253.             a = a*2 | bmp[i*8 +3][j];  
  254.             a = a*2 | bmp[i*8 +2][j];  
  255.             a = a*2 | bmp[i*8 +1][j];                         
  256.             a = a*2 | bmp[i*8 +0][j];  
  257.             fprintf(fo4,"0x%02x,",a);//输出数据  
  258.             a = 0;  
  259.         }         
  260.         fprintf(fo4,"/n/t");  
  261.     }  
  262.     fprintf(fo4,"/n};");  
  263. }  
  264.   
  265.   
  266. int main(void)  
  267. {  
  268.   
  269.     hexLogView_horizontal(unicomLogo,sizeof(unicomLogo)-1);//联通的logo,水平扫描的  
  270.     hexLogView_vertical(cmccLogo,sizeof(cmccLogo));//移动的logo,垂直扫描的  
  271.     bmpInfLen =  bmpTohex("logo.bmp","logo.txt",bmpinf);//把logo.bmp文件按16进制读取然后写入到文件logo.txt和全局数组bmpinf中  
  272.     bmpInfToArray(bmpinf);//全局数组bmpinf中的数据按水平和垂直扫描方式转换成数组分别存到两个文件中  
  273. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值