stm32显示bmp图片

这篇具有很好参考价值的文章主要介绍了stm32显示bmp图片。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.介绍

2.代码

2.1 定义

2.2 图片显示

2.3 格式转换

3.实现效果

4.源码地址


1.介绍

使用stm32单片机将bmp格式的图片显示在屏幕上,如果图片尺寸大于屏幕就将其缩放,图片文件存储在sd卡中,因此显示图片需要首先实现文件系统的移植及lcd屏幕的驱动(本文不涉及这一部分),本文主要实现图片处理这一部分。图片显示的原理就是通过文件系统打开图片文件,读取各像素点的颜色值进行处理后,使用屏幕显示出来。

注:文末给出的例程,部分驱动代码参考了正点原子的代码,例程仅供参考,如有问题,请自行修改。

2.代码

2.1 定义

主要定义了结构体Picture,用来存放图片的宽度,高度等相关信息。

#define P_LEN 240//屏幕宽度;
#define P_HEN 320//屏幕高度;

struct picture
{
	uint8_t 	bmphead[54];	//图片头信息;
	uint16_t  	offset;			//图像数据在文件中的偏移量;
	uint16_t  	hight;			//图片高度(像素点的个数);
	uint16_t  	weight;			//图片宽度;
	uint32_t  	size;			//图片的大小;
	uint32_t  	count;			//几位色彩;
	uint32_t  	color[P_LEN];	//处理后的像素的颜色值;
	uint8_t 	rgba[4 * P_LEN];//处理前的像素的颜色值;
}Picture;

2.2 图片显示

函数LCD_Show_Bmp,就是实现图片显示的主要函数,只需要在主函数中调用该函数传入图片名,就能将图片显示在屏幕上。

void LCD_Show_Bmp(char *pn)
{
	uint8_t kes = 0, ucRes;
	FIL ftp;//文件指针;
	char pname[100];//打开的图片文件名;
	int i = 0;
	uint32_t brt;
	
	uint32_t Pb = 0;//需要的像素点索引;
	uint32_t P_L = 0;//缩放后的图片宽度(即实际屏幕上显示的);
	uint32_t P_H = 0;//缩放后的图片高度;

	uint32_t P_X = 0;//显示图片的X起始坐标;
	uint32_t P_Y = 0;//显示图片的Y起始坐标;

	uint32_t pl = 0; //行像素;

	uint32_t len1 = 0, len2 = 0;//图片的宽度可能很宽,每次只取240个像素点,
								//len1表示取的次数,len2表示剩下不足240的像素数;
	
	float P_mag;//缩放比例;
	uint32_t mt1 = 0, mt2 = 0;//与缩放比例有关;
	
	pname[0] = '0';//存储的路径;
	pname[1] = ':';
	while(pn[i] != '\0')
	{
		pname[i + 2] = pn[i];
		i++;
	}
	
	pname[i + 2] = '\0';
	
	kes = PutGetFile_Sys(); //挂载文件系统;
	if(kes == 0)
	{
		printf("文件系统挂载失败!\n");
		return;
	}
	
	ucRes = f_open(&ftp, pname, FA_OPEN_ALWAYS | FA_READ | FA_WRITE);//打开bmp格式的图片文件;
	if(ucRes != 0)
	{
		printf("图片文件打开失败!\n");
		return;
	}
	
	f_lseek(&ftp, 0);
	f_read(&ftp, Picture.bmphead, 54, &brt);//读取文件头信息;
		
	//计算偏移量,宽度,高度等;
	Picture.offset = Picture.bmphead[10] + Picture.bmphead[11] * 256 + Picture.bmphead[12] * 256 * 256 + Picture.bmphead[13] * 256 * 256 * 256;
	Picture.weight = Picture.bmphead[18] + Picture.bmphead[19] * 256 + Picture.bmphead[20] * 256 * 256 + Picture.bmphead[21] * 256 * 256 * 256;
	Picture.hight  = Picture.bmphead[22] + Picture.bmphead[23] * 256 + Picture.bmphead[24] * 256 * 256 + Picture.bmphead[25] * 256 * 256 * 256;
	Picture.size   = Picture.bmphead[2]  + Picture.bmphead[3]  * 256 + Picture.bmphead[4]  * 256 * 256 + Picture.bmphead[5]  * 256 * 256 * 256;
	Picture.count  = Picture.bmphead[28] / 8;
	
	len1 = Picture.weight / P_LEN;
	len2 = Picture.weight % P_LEN;
	
	if(Picture.weight > P_LEN || Picture.hight > P_HEN)
	{
		if(((float)Picture.weight / (float)P_LEN) >= ((float)Picture.hight / (float)P_HEN))
		{
			P_mag = ((float)Picture.weight / (float)P_LEN);
			P_L = P_LEN;
			P_H = P_rand((float)Picture.hight / P_mag);

			P_X = 0;
			P_Y = P_HEN - ((P_HEN - P_H) / 2);
			
			mt1 = Picture.weight;
			mt2 = P_LEN;
		}
		else
		{
			P_mag = ((float)Picture.hight / (float)P_HEN);
			P_H = P_HEN;
			P_L = P_rand((float)Picture.weight / P_mag);
			
			P_X = ((P_LEN - P_L) / 2);
			P_Y = P_HEN;
			
			mt1 = Picture.hight;
			mt2 = P_HEN;
		}

	}
	else
	{
		P_mag = 1;
		P_L = Picture.weight;
		P_H = Picture.hight;

		P_X = ((P_LEN - P_L) / 2);
		P_Y = P_HEN - ((P_HEN - P_H) / 2);
		
		mt1 = 1;
		mt2 = 1;
	}
	
	for(int k = P_H; k > 0; k --)
	{
		pl = 0;
		for(int m = 0; m < len1; m++)
		{
			f_lseek(&ftp, Picture.offset + (P_mand(mt1, mt2, (k - 1)) * Picture.weight + m * P_LEN)* Picture.count);
			f_read(&ftp, Picture.rgba, Picture.count * P_LEN, &brt);
			
			for(int j = pl; j < P_L; j ++)
			{
				Pb = P_mand(mt1, mt2, j);
				
				if(Pb < (m + 1) * P_LEN)
				{
					Picture.color[j] = P_TranColor(Picture.rgba[(Pb % P_LEN) * Picture.count + 0], Picture.rgba[(Pb % P_LEN) * Picture.count + 1 ], Picture.rgba[(Pb % P_LEN) * Picture.count + 2]);
				}
				else
				{
					pl = j;
					break;
				}
			}
		}

		f_lseek(&ftp, Picture.offset + (P_mand(mt1, mt2, (k - 1)) * Picture.weight + len1 * P_LEN) * Picture.count);
		f_read(&ftp, Picture.rgba, Picture.count * len2, &brt);
		
		for(int j = pl; j < P_L; j ++)
		{
			Pb = P_mand(mt1, mt2, j);

			if(Pb < (len1 * P_LEN + len2))
			{
				Picture.color[j] = P_TranColor(Picture.rgba[(Pb % P_LEN) * Picture.count + 0], Picture.rgba[(Pb % P_LEN) * Picture.count + 1 ], Picture.rgba[(Pb % P_LEN) * Picture.count + 2]);			
			}
			else
			{
				pl = j;
				break;
			}
		}
		
		LCD_SetCursor(P_X, P_Y - 1 - (k - 1));
		LCD_WriteRAM_Start();
		for(int kt = 0; kt < P_L; kt++)
		{
			LCD_SendData(Picture.color[kt]);
		}
	}
	
	f_close(&ftp);
}

2.3 格式转换

uint16_t P_TranColor(uint8_t P_Blue, uint8_t P_Green, uint8_t P_Red)//24位(RGBA格式实际为32位,最后8位舍弃)转为16位颜色;
{
    uint16_t P_Color = 0;
    P_Color = (uint16_t)(P_Blue >> 3) | ((uint16_t)(P_Green >> 2) << 5) | ((uint16_t)(P_Red >> 3) << 11);
    return P_Color;
}

/*缩放图片(通过四舍五入找出需要的像素点)*/
int P_mand(int len1, int len2, int num) //原始图片像素数/屏幕实际像素数 * 第几个像素;
{
    int sum = 0;
    sum = (len1 * num) / len2;
    
    if( 2 * ((len1 * num) % len2) >= len2)
    {
        sum += 1;
    }
    return sum;
}

int P_rand(float temp)//将小数四舍五入成整数;
{
    int kemp = 0;
    float memp = 0;
    kemp = (int)temp;
    memp = temp - kemp;
    if(memp >= 0.5)
    {
        kemp = kemp + 1;
    }

    return kemp;
}

3.实现效果

将图片拷贝到sd卡,插入开发板中,然后将程序下载到开发板中,本文中使用的正点原子的stm32mini板,其他开发板视情况自行修改,效果如下:

stm32gifbmp图,stm32,单片机,嵌入式硬件stm32gifbmp图,stm32,单片机,嵌入式硬件

4.源码地址

百度网盘地址:https://pan.baidu.com/s/1eMTKy2vSxBybVcjuAfkY5Q?pwd=31ji 提取码: 31ji文章来源地址https://www.toymoban.com/news/detail-517364.html

到了这里,关于stm32显示bmp图片的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【单片机毕设选题】 stm32智能运动计步系统 - 物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(67)
  • 单片机项目分享 stm32机器视觉的口罩佩戴检测系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月22日
    浏览(83)
  • 【单片机毕设选题】Stm32单片机的音乐播放器设计 - 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(52)
  • 单片机项目分享 单片机自动写字机器人设计与实现 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月21日
    浏览(95)
  • stm32毕设分享 Stm32酒驾检查系统 - 单片机 嵌入式 物联网

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年01月23日
    浏览(76)
  • stm32毕设分享 stm32实现车牌识别系统 -物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(63)
  • 嵌入式STM32 单片机 GPIO 的工作原理详解

    STM32的 GPIO 介绍 GPIO 是通用输入/输出端口的简称,是 STM32 可控制的引脚。GPIO 的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 以 STM32F103ZET6 芯片为例子,该芯片共有 144 脚芯片,包括7个通用目的的输入/输出口(GPIO)组,分别为

    2024年02月20日
    浏览(50)
  • 【单片机毕设选题】 单片机自动写字机器人设计与实现 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月02日
    浏览(62)
  • 单片机毕设分享 基于STM32单片机的老人防摔倒报警系统 - 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月02日
    浏览(71)
  • 单片机项目分享 单片机家用燃气的可视化实时监控报警仪 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月22日
    浏览(75)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包