提取bmp图片的颜色信息,可直接framebuffer显示(c版本与python版本)
稍微了解了下linux的framebuffer,这是一种很简单的显示接口,直接写入像素信息即可
配置好的内核,会有/dev/fbn 的接口,于是想能否提前生成一个文件,比如logo.fb,里面仅包含像素信息,从而可以直接送入framebuffer显示
搜索了一下,有不少文章介绍,如何解析bmp图片并送给framebuffer显示,但没有找到预处理工具,都是直接处理完就送入framebuffer
于是参考了一篇文章,改动了下代码,将直接送入framebuffer变成写到一个文件中。
原代码地址为
1 | http: //blog.csdn.net/xsckernel/article/details/49992315 |
测试得到的文件,是可以直接 cat logo.fb > /dev/fb0 进行显示的
注意:这个程序是给我那个24位的屏用的,如果是32位或者16位的话需要修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <linux/fb.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <arpa/inet.h> #include <errno.h> //author:http://blog.csdn.net/xsckernel/article/details/49992315 //modify :zqb-all //14byte文件头 typedef struct { char cfType[2]; //文件类型,"BM"(0x4D42) int cfSize; //文件大小(字节) int cfReserved; //保留,值为0 int cfoffBits; //数据区相对于文件头的偏移量(字节) }__attribute__((packed)) BITMAPFILEHEADER; //__attribute__((packed))的作用是告诉编译器取消结构在编译过程中的优化对齐 //40byte信息头 typedef struct { char ciSize[4]; //BITMAPFILEHEADER所占的字节数 int ciWidth; //宽度 int ciHeight; //高度 char ciPlanes[2]; //目标设备的位平面数,值为1 int ciBitCount; //每个像素的位数 char ciCompress[4]; //压缩说明 char ciSizeImage[4]; //用字节表示的图像大小,该数据必须是4的倍数 char ciXPelsPerMeter[4]; //目标设备的水平像素数/米 char ciYPelsPerMeter[4]; //目标设备的垂直像素数/米 char ciClrUsed[4]; //位图使用调色板的颜色数 char ciClrImportant[4]; //指定重要的颜色数,当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要 }__attribute__((packed)) BITMAPINFOHEADER; typedef struct { unsigned char blue; unsigned char green; unsigned char red; unsigned char reserved; }__attribute__((packed)) PIXEL; //颜色模式RGB BITMAPFILEHEADER FileHead; BITMAPINFOHEADER InfoHead; static char *fbp = 0; static int xres = 0; static int yres = 0; static int bits_per_pixel = 0; int width, height; int show_bmp(); int fbfd = 0; static int cursor_bitmap_format_convert( char *dst, char *src) { int i ,j ; char *psrc = src ; char *pdst = dst; char *p = psrc; /* 由于bmp存储是从后面往前面,所以需要倒序进行转换 */ pdst += (width * height * 3); for (i=0;i<height;i++){ p = psrc + (i+1) * width * 3; for (j=0;j<width;j++){ pdst -= 3; p -= 3; pdst[0] = p[0]; pdst[1] = p[1]; pdst[2] = p[2]; } } return 0; } int show_bmp( char *path, char *fb_path) { int i; FILE *fp,*fb_file; int rc; int line_x, line_y; long int location = 0, BytesPerLine = 0; char *bmp_buf = NULL; char *bmp_buf_dst = NULL; char * buf = NULL; int flen = 0; int ret = -1; int total_length = 0; printf ( "into show_bmp function\n" ); if (path == NULL || fb_path == NULL) { printf ( "path Error,return\n" ); return -1; } printf ( "path = %s\n" , path); fp = fopen ( path, "rb" ); if (fp == NULL){ printf ( "load cursor file open failed\n" ); return -1; } printf ( "fb_path = %s\n" , fb_path); fb_file = fopen ( fb_path, "wb" ); if (fp == NULL){ printf ( "load cursor file open failed\n" ); return -1; } /* 求解文件长度 */ fseek (fp,0,SEEK_SET); fseek (fp,0,SEEK_END); flen = ftell (fp); printf ( "flen is %d\n" ,flen); bmp_buf = ( char *) calloc (1,flen - 54); if (bmp_buf == NULL){ printf ( "load > malloc bmp out of memory!\n" ); return -1; } /* 再移位到文件头部 */ fseek (fp,0,SEEK_SET); rc = fread (&FileHead, sizeof (BITMAPFILEHEADER),1, fp); if ( rc != 1) { printf ( "read header error!\n" ); fclose ( fp ); return ( -2 ); } //检测是否是bmp图像 if ( memcmp (FileHead.cfType, "BM" , 2) != 0) { printf ( "it's not a BMP file\n" ); fclose ( fp ); return ( -3 ); } rc = fread ( ( char *)&InfoHead, sizeof (BITMAPINFOHEADER),1, fp ); if ( rc != 1) { printf ( "read infoheader error!\n" ); fclose ( fp ); return ( -4 ); } width = InfoHead.ciWidth; height = InfoHead.ciHeight; printf ( "FileHead.cfSize =%d byte\n" ,FileHead.cfSize); printf ( "flen = %d\n" , flen); printf ( "width = %d, height = %d\n" , width, height); total_length = width * height *3; printf ( "total_length = %d\n" , total_length); //跳转的数据区 fseek (fp, FileHead.cfoffBits, SEEK_SET); printf ( " FileHead.cfoffBits = %d\n" , FileHead.cfoffBits); printf ( " InfoHead.ciBitCount = %d\n" , InfoHead.ciBitCount); //每行字节数 buf = bmp_buf; while ((ret = fread (buf,1,total_length,fp)) >= 0) { if (ret == 0) { usleep(100); continue ; } printf ( "ret = %d\n" , ret); buf = (( char *) buf) + ret; total_length = total_length - ret; if (total_length == 0) break ; } ///重新计算,很重要!! total_length = width * height *3; bmp_buf_dst = ( char *) calloc (1,total_length ); if (bmp_buf_dst == NULL){ printf ( "load > malloc bmp out of memory!\n" ); return -1; } cursor_bitmap_format_convert(bmp_buf_dst, bmp_buf); fwrite (bmp_buf_dst,1,total_length,fb_file); free (bmp_buf); free (bmp_buf_dst); fclose (fp); fclose (fb_file); printf ( "show logo return 0\n" ); return 0; } int main() { show_bmp( "./logo.bmp" , "./logo.fb" ); } |
测试可用后,又想到,这是在我的主机上做的预处理,那完全可以不用c语言呀,搞点简洁些的,比如python
于是有了这个python版本
要安装PIL
1 | sudo apt-get install python-imaging |
PIL介绍就不多说了,我也是第一次用,大家搜一下很多介绍文章的,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/usr/bin/env python2 import struct from PIL import Image im = Image. open ( 'logo.bmp' ) w, h = im.size print ( "w:" , w , "h:" , h) with open ( 'logo.fb' , 'wb' ) as f: for j in range ( 0 ,h): for i in range ( 0 ,w): r,g,b = im.getpixel((i,j)) rgb = struct.pack( 'BBB' ,b,g,r) f.write(rgb); |
补充,Python版本的拓展:
请查看文章 python将图片转换为Framebuffer裸数据格式(终端显示图片) 或代码 https://github.com/zqb-all/convertfb
本文地址:http://www.cnblogs.com/zqb-all/p/6080429.html
作者:zqb-all
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
欢迎扫描左侧二维码关注微信公众号 QB杂货铺
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步