提取bmp图片的颜色信息,可直接framebuffer显示(c版本与python版本)
底层劳动人民的不解忧杂货铺

提取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

    posted @   zqb-all  阅读(2175)  评论(0编辑  收藏  举报
    点击右上角即可分享
    微信分享提示