查看: 283|回复: 0

[经验] 飞凌嵌入式ElfBoard ELF1板卡-显示bmp图片代码

[复制链接]

该用户从未签到

发表于 2024-11-23 11:48:22 | 显示全部楼层 |阅读模式
分享到:
注意:学习资料可在ElfBoard官方网站“资料”专区获取。
本节用到的源码路径:ELF 1开发板资料包\03-例程源码\03-1 命令行例程源码\07_elf1_cmd_bmp
bmp.c
  1. #include "bmp.h"

  2. /*
  3. * @description     : 图片显示函数
  4. * @param - *fbp    : 映射内存起始地址
  5. * @param - *scrinfo: 屏幕信息结构体
  6. * @param - *bmpname: .bmp位图文件名
  7. * @return                    : 执行结果
  8. */
  9. int show_photo(const char *fbp, struct fb_var_screeninfo *scrinfo, const char *bmpname, char mode)
  10. {
  11.     if (NULL == fbp || NULL == scrinfo || NULL == bmpname)
  12.         return -1;

  13.     int line_x = 0, line_y = 0;
  14.     unsigned long tmp32 = 0;
  15.     unsigned int tmp = 0;
  16.     int xres = scrinfo->xres_virtual;             //屏幕宽(虚拟)
  17.     int bits_per_pixel = scrinfo->bits_per_pixel; //屏幕位数
  18.     BitMapFileHeader FileHead;
  19.     BitMapInfoHeader InfoHead;
  20.     RgbQuad rgb;

  21.     unsigned long location = 0;

  22.     //打开.bmp文件
  23.     FILE *fb = fopen(bmpname, "rb");
  24.     if (fb == NULL)
  25.     {
  26.         printf("fopen bmp error\r\n");
  27.         return -1;
  28.     }

  29.     //读文件信息
  30.     if (1 != fread(&FileHead, sizeof(BitMapFileHeader), 1, fb))
  31.     {
  32.         printf("read BitMapFileHeader error!\n");
  33.         fclose(fb);
  34.         return -1;
  35.     }
  36.     if (memcmp(FileHead.bfType, "BM", 2) != 0)
  37.     {
  38.         printf("it's not a BMP file\n");
  39.         fclose(fb);
  40.         return -1;
  41.     }

  42.     //读位图信息
  43.     if (1 != fread((char *)&InfoHead, sizeof(BitMapInfoHeader), 1, fb))
  44.     {
  45.         printf("read BitMapInfoHeader error!\n");
  46.         fclose(fb);
  47.         return -1;
  48.     }

  49.     //跳转至数据区
  50.     fseek(fb, FileHead.bfOffBits, SEEK_SET);

  51.     int len = InfoHead.biBitCount / 8; //原图一个像素占几字节
  52.     int bits_len = bits_per_pixel / 8; //屏幕一个像素占几字节//循环显示

  53.     while (!feof(fb))
  54.     {
  55.         tmp = 0;
  56.         tmp32 = 0;
  57.         rgb.Reserved = 0xFF;

  58.         if (len != fread((char *)&rgb, 1, len, fb))
  59.             break;

  60.         //计算该像素在映射内存起始地址的偏移量
  61.         location = line_x * bits_len + (InfoHead.biHeight - line_y - 1) * xres * bits_len;

  62.         if (BIT32 == mode)
  63.         {
  64.             tmp32 |= rgb.Reserved << 24 | rgb.Red << 16 | rgb.Green << 8 | rgb.Blue; // RGB888
  65.             *((unsigned long *)(fbp + location)) = tmp32;
  66.         }
  67.         else if (BIT16 == mode)
  68.         {
  69.             tmp |= (rgb.Red >> 3) << 11 | (rgb.Green >> 2) << 5 | rgb.Blue >> 3; // RGB565
  70.             *((unsigned short *)(fbp + location)) = tmp;
  71.         }
  72.         else
  73.                 break;

  74.         line_x++;
  75.         if (line_x == InfoHead.biWidth)
  76.         {
  77.             line_x = 0;
  78.             line_y++;
  79.             if (line_y == InfoHead.biHeight)
  80.                 break;
  81.         }
  82.     }

  83.     fclose(fb);

  84.     return 0;
  85. }
复制代码
bmp.h
  1. #ifndef __BMP_H__
  2. #define __BMP_H__

  3. #include <unistd.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <fcntl.h>
  7. #include <string.h>
  8. #include <linux/fb.h>
  9. #include <sys/mman.h>
  10. #include <sys/ioctl.h>
  11. #include <arpa/inet.h>

  12. #define BIT16 0
  13. #define BIT32 1

  14. //文件头结构体
  15. typedef struct
  16. {
  17.     unsigned char bfType[2];                //文件类型
  18.     unsigned long bfSize;                   //位图大小
  19.     unsigned short bfReserved1;             //位0
  20.     unsigned short bfReserved2;             //位0
  21.     unsigned long bfOffBits;                //到数据偏移量
  22. } __attribute__((packed)) BitMapFileHeader; //使编译器不优化,其大小为14字节

  23. //信息头结构体
  24. typedef struct
  25. {
  26.     unsigned long biSize;         // BitMapFileHeader 字节数
  27.     long biWidth;                 //位图宽度
  28.     long biHeight;                //位图高度,正位正向,反之为倒图
  29.     unsigned short biPlanes;      //为目标设备说明位面数,其值将总是被设为1
  30.     unsigned short biBitCount;    //说明比特数/象素,为1、4、8、16、24、或32。
  31.     unsigned long biCompression;  //图象数据压缩的类型没有压缩的类型:BI_RGB
  32.     unsigned long biSizeImage;    //说明图象的大小,以字节为单位
  33.     long biXPelsPerMeter;         //说明水平分辨率
  34.     long biYPelsPerMeter;         //说明垂直分辨率
  35.     unsigned long biClrUsed;      //说明位图实际使用的彩色表中的颜色索引数
  36.     unsigned long biClrImportant; //对图象显示有重要影响的索引数,0都重要。
  37. } __attribute__((packed)) BitMapInfoHeader;

  38. //像素点结构体
  39. typedef struct
  40. {
  41.     unsigned char Blue;     //该颜色的蓝色分量
  42.     unsigned char Green;    //该颜色的绿色分量
  43.     unsigned char Red;      //该颜色的红色分量
  44.     unsigned char Reserved; //保留值(亮度)
  45. } __attribute__((packed)) RgbQuad;

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

  47. #endif //__BMP_H__
复制代码
main.c
  1. #include "bmp.h"

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

  3. int dev_fd;
  4. char dev[20];

  5. char rgb_mode = BIT16; // BIT16-16位屏幕  BIT32-32位屏幕
  6. char bmpname[50] = {0};

  7. /*
  8. * @description  : 打印参数设置格式
  9. * @param - pname: 函数名
  10. * @return                 : 无
  11. */
  12. static void print_usage(const char *pname)
  13. {
  14.     printf("Usage: %s device [-b bits] [-n bmpname] [-v]"
  15.            "\n\t'-b bits' for 16 bits_per_pixel or 32 bits_per_pixel"
  16.            "\n\t'-n bmpname' for the bmp file name containing the path "
  17.            "\n\t'-v' show version"
  18.            "\n\texample :  --> ./elf1_cmd_lcd_bmp fb0 -b 16 -n /home/root/test1.bmp\n ",
  19.            pname);
  20. }

  21. /*
  22. * @description   : 解析函数带入参数
  23. * @param - numb  : 参数个数
  24. * @param - *param: 带入参数数组指针
  25. * @return                  : 无
  26. */
  27. void get_param(int numb, char *param[])
  28. {
  29.     int i = 0;
  30.     int temp = 0;

  31.     if (numb <= 2)
  32.         return;

  33.     for (i = 2; i < numb; i++)
  34.     {
  35.         if (!strcmp(param[i], "-b"))
  36.         {
  37.             i++;

  38.             temp = atoi(param[i]);
  39.             if (16 == temp)
  40.             {
  41.                 rgb_mode = BIT16;
  42.             }
  43.             else if (32 == temp)
  44.             {
  45.                 rgb_mode = BIT32;
  46.             }
  47.             continue;
  48.         }
  49.         if (!strcmp(param[i], "-n"))
  50.         {
  51.             i++;
  52.             strcpy(bmpname, param[i]);
  53.             printf("%s", bmpname);
  54.             continue;
  55.         }
  56.         if (!strcmp(param[i], "-v"))
  57.         {
  58.             printf("tty_demo ver:  %s\n", ver);
  59.             continue;
  60.         }
  61.     }
  62. }

  63. /*
  64. * @description  : 主函数
  65. * @param - argc : 参数个数
  66. * @param - *argv: 带入参数数组指针
  67. * @return                 : 执行结果
  68. */
  69. int main(int argc, char *argv[])
  70. {
  71.     struct fb_var_screeninfo scrinfo;
  72.     unsigned long screensize;
  73.     char *fbp;

  74.     //检测是否有参数
  75.     if (argc < 2)
  76.     {
  77.         print_usage(argv[0]);
  78.         exit(1);
  79.     }

  80.     //检测是否有--h或--help
  81.     if ((!strcmp(argv[1], "--h")) || (!strcmp(argv[1], "--help")))
  82.     {
  83.         print_usage(argv[0]);
  84.         exit(1);
  85.     }

  86.     strcpy(dev, "/dev/");
  87.     strcat(dev, argv[1]);

  88.     //从main函数带入的参数解析
  89.     get_param(argc, argv);

  90.     //当知道设备名称时可以直接赋值dev,例strcpy(dev, "/dev/fb0");
  91.     //打开屏幕外设
  92.     dev_fd = open(dev, O_RDWR);
  93.     if (!dev_fd)
  94.     {
  95.         printf("dev_fd open error!\r\n");
  96.         return -1;
  97.     }
  98.     // printf("dev_fd open OK! %d\r\n", dev_fd);

  99.     //获取屏幕信息
  100.     //若屏幕显示区域大小不合适,可用ioctl(dev_fd, FBIOPUT_VSCREENINFO, &scrinfo)设置
  101.     if (ioctl(dev_fd, FBIOGET_VSCREENINFO, &scrinfo))
  102.     {
  103.         printf("get screen infomation error!\r\n");
  104.         return -1;
  105.     }

  106.     //打印屏幕信息
  107.     printf(".xres=%d, .yres=%d, .bit=%d\r\n", scrinfo.xres, scrinfo.yres, scrinfo.bits_per_pixel);
  108.     printf(".xres_virtual=%d, .yres_virtual=%d\r\n", scrinfo.xres_virtual, scrinfo.yres_virtual);

  109.     if (((16 != scrinfo.bits_per_pixel) && (BIT16 == rgb_mode)) ||
  110.         ((32 != scrinfo.bits_per_pixel) && (BIT32 == rgb_mode)))
  111.     {
  112.         printf("screen infomation.bits error!\r\n");
  113.         return -1;
  114.     }

  115.     //计算需要的映射内存大小
  116.     screensize = scrinfo.xres_virtual * scrinfo.yres_virtual * scrinfo.bits_per_pixel / 8;
  117.     // printf("screensize=%lu!\r\n", screensize);

  118.     //内存映射
  119.     fbp = (char *)mmap(NULL, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0);
  120.     if (-1 == (int)fbp)
  121.     {
  122.         printf("mmap error!\r\n");
  123.         return -1;
  124.     }

  125.     //显示图片
  126.     show_photo(fbp, &scrinfo, bmpname, rgb_mode);

  127.     //取消映射,关闭文件
  128.     munmap(fbp, screensize);
  129.     close(dev_fd);

  130.     return 0;
  131. }
复制代码
进程名:elf1_cmd_lcd_bmp
使用方法:./elf1_cmd_lcd_bmp 设备名 [参数选项]… …
Image_20241123114725.png

回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /4 下一条



手机版|小黑屋|与非网

GMT+8, 2024-12-18 20:40 , Processed in 0.123256 second(s), 17 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.