设计程序实现在LCD上任意位置显示一张任意大小的色深为 24bit的bmp图片,要求图像不失真可以在开发板的LCD上显示。
头文件包含
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <strings.h>
//以1字节对齐方式对齐
#pragma pack(1)// 定义BMP文件头部结构
typedef struct
{unsigned short bfType;unsigned int bfSize;unsigned short bfReserved1;unsigned short bfReserved2;unsigned int bfOffBits;
} BITMAPFILEHEADER;typedef struct
{unsigned int biSize;int biWidth; // 宽int biHeight; // 高unsigned short biPlanes;unsigned short biBitCount; // 色深unsigned int biCompression;unsigned int biSizeImage;int biXPelsPerMeter;int biYPelsPerMeter;unsigned int biClrUsed;unsigned int biClrImportant;
} BITMAPINFOHEADER;
//取消字节对齐
#pragma pack()
/********************************************************************* 函数名称: ShowBmp* 函数功能: 在LCD上任意位置显示一张任意大小的色深为 24bit的bmp图片* 函数参数:* @name bmp图像文件名* @x 图像显示的起点x轴坐标* @y 图像显示的起点y轴左边* @lcd_mp lcd屏内存映射的地址* 返回结果:* 注意事项: None* 函数作者: mailLinL@163.com* 创建日期: 2024/05/12* 修改历史:* 函数版本: V1.0* *****************************************************************/
int ShowBmp(char *name, int x, int y, int *lcd_mp)
{// 1.打开待显示的BMP图像 fopenFILE *bmp_fp = fopen(name, "rb");if (NULL == bmp_fp){printf("open FILE is error!\n");return -1;}// 2.读取BMP文件的图像信息,获取BMP的宽和高BITMAPINFOHEADER headinfo;fseek(bmp_fp, 14, SEEK_SET);fread(&headinfo, 1, 40, bmp_fp); // 读取40字节// 打开LCD openint lcd_fd = open("/dev/fb0", O_RDWR);if (lcd_fd == -1){printf("mmap for lcd is error\n");return -1;}// 调用LCD屏的像素struct fb_var_screeninfo lcd_vinfo;ioctl(lcd_fd, FBIOGET_VSCREENINFO, &lcd_vinfo);// 3.读取BMP图片的颜色分量char bmp_buf[headinfo.biWidth * headinfo.biHeight * 3];bzero(bmp_buf, headinfo.biWidth * headinfo.biHeight * 3);fread(bmp_buf, 1, headinfo.biWidth * headinfo.biHeight * 3, bmp_fp);printf("bmp width = %d,height = %d\n", headinfo.biWidth, headinfo.biHeight);// 4.关闭BMPfclose(bmp_fp);// 5.循环将bmp图像写入lcd屏指定位置int data = 0;int i = 0;for (int h = (y + headinfo.biHeight - 1); h >= y; h--){for (int w = x; w < (x + headinfo.biWidth); w++){data |= bmp_buf[i];data |= bmp_buf[i + 1] << 8;data |= bmp_buf[i + 2] << 16;lcd_mp[h * (lcd_vinfo.xres) + w] = data;i += 3;data = 0;}}// 关闭LCDclose(lcd_fd);munmap(lcd_mp, lcd_vinfo.xres * lcd_vinfo.yres * 4);return 0;
}
int main(int argc, char *argv[])
{if (argc != 2){printf("argument is error!\n");return -1;}if (NULL == argv[1]){printf("argument 2 is error!\n");return -1;}// 打开LCD openint lcd_fd = open("/dev/fb0", O_RDWR);if (lcd_fd == -1){printf("mmap for lcd is error\n");return -1;}// 调用LCD屏的像素struct fb_var_screeninfo lcd_vinfo;ioctl(lcd_fd, FBIOGET_VSCREENINFO, &lcd_vinfo);// 对LCD进行内存映射 mmapint *lcd_mp = (int *)mmap(NULL,lcd_vinfo.xres * lcd_vinfo.yres * 4,PROT_READ | PROT_WRITE,MAP_SHARED,lcd_fd,0);// 键盘输入图片显示的起始位置int x, y;scanf("%d%d", &x, &y);ShowBmp(argv[1], x, y, lcd_mp);// 关闭LCDmunmap(lcd_mp, lcd_vinfo.xres * lcd_vinfo.yres * 4);close(lcd_fd);return 0;
}
测试结果