加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
    • bmp.c
    • bmp.h
    • main.c
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之显示bmp图片代码

5小时前
252
阅读需 18 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

注意:学习资料可在ElfBoard官方网站“资料”专区获取。

本节用到的源码路径:ELF 1开发板资料包3-例程源码3-1 命令行例程源码7_elf1_cmd_bmp

bmp.c

#include "bmp.h"




/*

 * @description     : 图片显示函数

 * @param - *fbp    : 映射内存起始地址

 * @param - *scrinfo: 屏幕信息结构体

 * @param - *bmpname: .bmp位图文件名

 * @return     : 执行结果

 */

int show_photo(const char *fbp, struct fb_var_screeninfo *scrinfo, const char *bmpname, char mode)

{

    if (NULL == fbp || NULL == scrinfo || NULL == bmpname)

        return -1;




    int line_x = 0, line_y = 0;

    unsigned long tmp32 = 0;

    unsigned int tmp = 0;

    int xres = scrinfo->xres_virtual;             //屏幕宽(虚拟)

    int bits_per_pixel = scrinfo->bits_per_pixel; //屏幕位数

    BitMapFileHeader FileHead;

    BitMapInfoHeader InfoHead;

    RgbQuad rgb;




    unsigned long location = 0;




    //打开.bmp文件

    FILE *fb = fopen(bmpname, "rb");

    if (fb == NULL)

    {

        printf("fopen bmp errorrn");

        return -1;

    }




    //读文件信息

    if (1 != fread(&FileHead, sizeof(BitMapFileHeader), 1, fb))

    {

        printf("read BitMapFileHeader error!n");

        fclose(fb);

        return -1;

    }

    if (memcmp(FileHead.bfType, "BM", 2) != 0)

    {

        printf("it's not a BMP filen");

        fclose(fb);

        return -1;

    }




    //读位图信息

    if (1 != fread((char *)&InfoHead, sizeof(BitMapInfoHeader), 1, fb))

    {

        printf("read BitMapInfoHeader error!n");

        fclose(fb);

        return -1;

    }




    //跳转至数据区

    fseek(fb, FileHead.bfOffBits, SEEK_SET);




    int len = InfoHead.biBitCount / 8; //原图一个像素占几字节

    int bits_len = bits_per_pixel / 8; //屏幕一个像素占几字节//循环显示




    while (!feof(fb))

    {

        tmp = 0;

        tmp32 = 0;

        rgb.Reserved = 0xFF;




        if (len != fread((char *)&rgb, 1, len, fb))

            break;




        //计算该像素在映射内存起始地址的偏移量

        location = line_x * bits_len + (InfoHead.biHeight - line_y - 1) * xres * bits_len;




        if (BIT32 == mode)

        {

            tmp32 |= rgb.Reserved << 24 | rgb.Red << 16 | rgb.Green << 8 | rgb.Blue; // RGB888

            *((unsigned long *)(fbp + location)) = tmp32;

        }

        else if (BIT16 == mode)

        {

            tmp |= (rgb.Red >> 3) << 11 | (rgb.Green >> 2) << 5 | rgb.Blue >> 3; // RGB565

            *((unsigned short *)(fbp + location)) = tmp;

        }

else

break;




        line_x++;

        if (line_x == InfoHead.biWidth)

        {

            line_x = 0;

            line_y++;

            if (line_y == InfoHead.biHeight)

                break;

        }

    }




    fclose(fb);




    return 0;

}

bmp.h

#ifndef __BMP_H__

#define __BMP_H__




#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>




#define BIT16 0

#define BIT32 1




//文件头结构体

typedef struct

{

    unsigned char bfType[2];                //文件类型

    unsigned long bfSize;                   //位图大小

    unsigned short bfReserved1;             //位0

    unsigned short bfReserved2;             //位0

    unsigned long bfOffBits;                //到数据偏移量

} __attribute__((packed)) BitMapFileHeader; //使编译器不优化,其大小为14字节




//信息头结构体

typedef struct

{

    unsigned long biSize;         // BitMapFileHeader 字节数

    long biWidth;                 //位图宽度

    long biHeight;                //位图高度,正位正向,反之为倒图

    unsigned short biPlanes;      //为目标设备说明位面数,其值将总是被设为1

    unsigned short biBitCount;    //说明比特数/象素,为1、4、8、16、24、或32。

    unsigned long biCompression;  //图象数据压缩的类型没有压缩的类型:BI_RGB

    unsigned long biSizeImage;    //说明图象的大小,以字节为单位

    long biXPelsPerMeter;         //说明水平分辨率

    long biYPelsPerMeter;         //说明垂直分辨率

    unsigned long biClrUsed;      //说明位图实际使用的彩色表中的颜色索引数

    unsigned long biClrImportant; //对图象显示有重要影响的索引数,0都重要。

} __attribute__((packed)) BitMapInfoHeader;




//像素点结构体

typedef struct

{

    unsigned char Blue;     //该颜色的蓝色分量

    unsigned char Green;    //该颜色的绿色分量

    unsigned char Red;      //该颜色的红色分量

    unsigned char Reserved; //保留值(亮度)

} __attribute__((packed)) RgbQuad;




int show_photo(const char *fbp, struct fb_var_screeninfo *scrinfo, const char *bmpname, char mode);




#endif //__BMP_H__

main.c

#include "bmp.h"




char ver[20] = {"ver01.001"};




int dev_fd;

char dev[20];




char rgb_mode = BIT16; // BIT16-16位屏幕  BIT32-32位屏幕

char bmpname[50] = {0};




/*

 * @description  : 打印参数设置格式

 * @param - pname: 函数名

 * @return  : 无

 */

static void print_usage(const char *pname)

{

    printf("Usage: %s device [-b bits] [-n bmpname] [-v]"

           "nt'-b bits' for 16 bits_per_pixel or 32 bits_per_pixel"

           "nt'-n bmpname' for the bmp file name containing the path "

           "nt'-v' show version"

           "ntexample :  --> ./elf1_cmd_lcd_bmp fb0 -b 16 -n /home/root/test1.bmpn ",

           pname);

}




/*

 * @description   : 解析函数带入参数

 * @param - numb  : 参数个数

 * @param - *param: 带入参数数组指针

 * @return   : 无

 */

void get_param(int numb, char *param[])

{

    int i = 0;

    int temp = 0;




    if (numb <= 2)

        return;




    for (i = 2; i < numb; i++)

    {

        if (!strcmp(param[i], "-b"))

        {

            i++;




            temp = atoi(param[i]);

            if (16 == temp)

            {

                rgb_mode = BIT16;

            }

            else if (32 == temp)

            {

                rgb_mode = BIT32;

            }

            continue;

        }

        if (!strcmp(param[i], "-n"))

        {

            i++;

            strcpy(bmpname, param[i]);

            printf("%s", bmpname);

            continue;

        }

        if (!strcmp(param[i], "-v"))

        {

            printf("tty_demo ver:  %sn", ver);

            continue;

        }

    }

}




/*

 * @description  : 主函数

 * @param - argc : 参数个数

 * @param - *argv: 带入参数数组指针

 * @return  : 执行结果

 */

int main(int argc, char *argv[])

{

    struct fb_var_screeninfo scrinfo;

    unsigned long screensize;

    char *fbp;




    //检测是否有参数

    if (argc < 2)

    {

        print_usage(argv[0]);

        exit(1);

    }




    //检测是否有--h或--help

    if ((!strcmp(argv[1], "--h")) || (!strcmp(argv[1], "--help")))

    {

        print_usage(argv[0]);

        exit(1);

    }




    strcpy(dev, "/dev/");

    strcat(dev, argv[1]);




    //从main函数带入的参数解析

    get_param(argc, argv);




    //当知道设备名称时可以直接赋值dev,例strcpy(dev, "/dev/fb0");

    //打开屏幕外设

    dev_fd = open(dev, O_RDWR);

    if (!dev_fd)

    {

        printf("dev_fd open error!rn");

        return -1;

    }

    // printf("dev_fd open OK! %drn", dev_fd);




    //获取屏幕信息

    //若屏幕显示区域大小不合适,可用ioctl(dev_fd, FBIOPUT_VSCREENINFO, &scrinfo)设置

    if (ioctl(dev_fd, FBIOGET_VSCREENINFO, &scrinfo))

    {

        printf("get screen infomation error!rn");

        return -1;

    }




    //打印屏幕信息

    printf(".xres=%d, .yres=%d, .bit=%drn", scrinfo.xres, scrinfo.yres, scrinfo.bits_per_pixel);

    printf(".xres_virtual=%d, .yres_virtual=%drn", scrinfo.xres_virtual, scrinfo.yres_virtual);




    if (((16 != scrinfo.bits_per_pixel) && (BIT16 == rgb_mode)) ||

        ((32 != scrinfo.bits_per_pixel) && (BIT32 == rgb_mode)))

    {

        printf("screen infomation.bits error!rn");

        return -1;

    }




    //计算需要的映射内存大小

    screensize = scrinfo.xres_virtual * scrinfo.yres_virtual * scrinfo.bits_per_pixel / 8;

    // printf("screensize=%lu!rn", screensize);




    //内存映射

    fbp = (char *)mmap(NULL, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0);

    if (-1 == (int)fbp)

    {

        printf("mmap error!rn");

        return -1;

    }




    //显示图片

    show_photo(fbp, &scrinfo, bmpname, rgb_mode);




    //取消映射,关闭文件

    munmap(fbp, screensize);

    close(dev_fd);




    return 0;

}

进程名:elf1_cmd_lcd_bmp

使用方法:./elf1_cmd_lcd_bmp 设备名 [参数选项]… …

相关推荐

电子产业图谱