LCD屏显示图片习题【一】

LCD屏显示图片习题

题目

image

解析

​ 该题的显著要求有两个,一是任意位置,二是任意大小。为满足这两个要求得先读取并记录bmp数据,且bmp文件属于普通文件,所以选择标准IO函数fopen()打开bmp,并用结构体变量进行记录;然后为了提升用户使用体验,即bmp在显示时不会出现黑线,对LCD屏进行内存映射,最后使用获取到的x1和y1作为循环条件,完成任意大小的bmp在任意位置显示。

image

代码完整展示

/*******************************************************************
*
*	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图像  fopen
	FILE * 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*3
	char *bmp_buf= calloc(1,3*(headerinfo.biWidth)*(headerinfo.biHeight));
	fread(bmp_buf,1,3*(headerinfo.biWidth)*(headerinfo.biHeight),bmp_fp);

	//4.关闭BMP
	fclose(bmp_fp);

	//5.打开LCD   open  
	int lcd_fd = open("/dev/fb0",O_RDWR);


	//6.对LCD进行内存映射  mmap
	int * 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 <--- BGR
			data |= bmp_buf[i];			//B
			data |= bmp_buf[i+1]<<8;	//G
			data |= bmp_buf[i+2]<<16;  	//R

			lcd_mp[800*y + x] = data;  //BGR BGR BGR .... 

			i+=3;  
			data = 0;
		}
	}
	
	//8.关闭LCD
	close(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;
}


posted @ 2024-05-13 08:33  飞子的唠唠叨  阅读(24)  评论(0编辑  收藏  举报