目录
- LCD屏显示图片习题
- 题目
- 解析
- 代码完整展示
LCD屏显示图片习题
题目
解析
该题的显著要求有两个,一是任意位置,二是任意大小。为满足这两个要求得先读取并记录bmp数据,且bmp文件属于普通文件,所以选择标准IO函数fopen()打开bmp,并用结构体变量进行记录;然后为了提升用户使用体验,即bmp在显示时不会出现黑线,对LCD屏进行内存映射,最后使用获取到的x1和y1作为循环条件,完成任意大小的bmp在任意位置显示。
代码完整展示
/*******************************************************************
*
* file name: ShowBmp.c
* author : 790557054@qq.com
* date : 2024/05/13
* function : 该案例是掌握LCD屏显示图片的基本原理
* note : None
*
* CopyRight (c) 2023-2024 790557054@qq.com All Right Reseverd
*
* *****************************************************************/#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdlib.h>//取消字节对齐
#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()/********************************************************************
*
* name : ShowBmp
* function : 实现任意图片大小在任意位置进行显示
* argument :
* @fname :需要显示的图片文件路径@x1 :图片显示位置的横坐标@y1 :图片显示位置的横坐标
*
* retval : 调用成功返回0,否则返回-1;
* author : 790557054@qq.com
* date : 2024/05/13
* note : none
*
* *****************************************************************/
int ShowBmp(const char *fname,int x1,int y1)
{//1.打开待显示的BMP图像 fopenFILE * bmp_fp = fopen(fname,"rb");if (NULL == bmp_fp){return -1;}//2.读取BMP文件的图像信息,获取BMP的宽和高BITMAPINFOHEADER headerinfo;BITMAPFILEHEADER fileinfo;fseek(bmp_fp,14,SEEK_SET);fread(&headerinfo,1,40,bmp_fp); //读取40字节printf("bmp width = %d,height = %d\n",headerinfo.biWidth,headerinfo.biHeight);//3.读取BMP图片的颜色分量 800*480*3char *bmp_buf= calloc(1,3*(headerinfo.biWidth)*(headerinfo.biHeight));fread(bmp_buf,1,3*(headerinfo.biWidth)*(headerinfo.biHeight),bmp_fp);//4.关闭BMPfclose(bmp_fp);//5.打开LCD open int lcd_fd = open("/dev/fb0",O_RDWR);//6.对LCD进行内存映射 mmapint * lcd_mp = (int *)mmap(NULL,4*800*480,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);//7.循环的把BMP图像的颜色分量依次写入到LCD的像素点中 int i = 0;int data = 0;//设置图片位置的关键在于循环条件,且要注意映射时需要从图片最后一行开始for (int y = 480 - (480 - headerinfo.biHeight - y1) - 1; y >= y1; y--){for (int x = x1; x < headerinfo.biWidth + x1; ++x){//把BMP图片的一个像素点的颜色分量转换为LCD屏幕的一个像素点的颜色分量格式 ARGB <--- BGRdata |= bmp_buf[i]; //Bdata |= bmp_buf[i+1]<<8; //Gdata |= bmp_buf[i+2]<<16; //Rlcd_mp[800*y + x] = data; //BGR BGR BGR .... i+=3; data = 0;}}//8.关闭LCDclose(lcd_fd);munmap(lcd_mp,800*480*4);return 0;
}
int main(int argc, char const *argv[])
{int x1 = 0, y1 = 0;//获取用户想要的图片显示位置printf("Please input x1 = \n");scanf("%d", &x1);printf("Please input y1 = \n");scanf("%d", &y1);//调用显示函数ShowBmp(argv[1],x1,y1);return 0;
}