硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1948|回复: 13
收起左侧

[有问必答] 求问如何在嵌入式单片机上实现截图功能?

[复制链接]

3

主题

20

回帖

29

积分

新手上路

积分
29
发表于 2022-9-16 15:49:35 | 显示全部楼层 |阅读模式
求教各位大佬,有没有一种方法可以实现单片机截图功能?
当前软硬件环境:
STM32F469 芯片, 跑的FreeRtos系统, 图形界面是用的飞思卡尔的D4D, 屏幕是320*240的LCD 彩屏。

目前需求是需要做屏幕流程文档,有没有方法可以实现屏幕截图功能?

有做过这种方案的大佬吗?
回复

使用道具 举报

86

主题

441

回帖

719

积分

金牌会员

积分
719
QQ
发表于 2022-9-16 16:44:39 | 显示全部楼层
可以直接读取显示缓存内容  保持为BMP格式
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116197
QQ
发表于 2022-9-16 16:57:37 | 显示全部楼层
最近正在开发一个给力的功能,替代传统的SD卡/U盘等存储方式。

H7-TOOL同步开发的还要一个重要功能,支持各种GUI的截图功能,无需再使用麻烦的SD卡/U盘截图方案
https://www.armbbs.cn/forum.php? ... 5414&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

3

主题

20

回帖

29

积分

新手上路

积分
29
 楼主| 发表于 2022-9-16 17:37:05 | 显示全部楼层
eric2013 发表于 2022-9-16 16:57
最近正在开发一个给力的功能,替代传统的SD卡/U盘等存储方式。

H7-TOOL同步开发的还要一个重要功能,支 ...

这个得有H7 tool才可以实现吧?
回复

使用道具 举报

3

主题

20

回帖

29

积分

新手上路

积分
29
 楼主| 发表于 2022-9-16 17:38:28 | 显示全部楼层
设备有USB功能,可以读写U盘
回复

使用道具 举报

3

主题

20

回帖

29

积分

新手上路

积分
29
 楼主| 发表于 2022-9-16 17:39:01 | 显示全部楼层
雷鹏 发表于 2022-9-16 16:44
可以直接读取显示缓存内容  保持为BMP格式

谢谢,有相关的实现参考代码吗?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116197
QQ
发表于 2022-9-17 00:51:52 | 显示全部楼层
Shawnx 发表于 2022-9-16 17:37
这个得有H7 tool才可以实现吧?

对,这个得需要TOOL。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116197
QQ
发表于 2022-9-17 00:52:36 | 显示全部楼层
Shawnx 发表于 2022-9-16 17:39
谢谢,有相关的实现参考代码吗?

自己搞的话,可以参考论坛置顶帖V5,V6,V7网盘的出厂程序,里面有个BMP格式文件保存方法,裸机UI的玩法,你应该可以直接复制使用的。
回复

使用道具 举报

10

主题

111

回帖

141

积分

初级会员

积分
141
发表于 2022-9-17 11:06:03 | 显示全部楼层
颜色格式固定(比如RGB565)分辨率固定,你把这个页面的缓存加上BMP格式的头通过串口等方式传到电脑然后16进制保存为BMP格式就好了。上位机就不需要你去做,当然如果你为了操作方便还是做个上位机好,这种东西非常简单的。
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
发表于 5 天前 | 显示全部楼层
eric2013 发表于 2022-9-17 00:52
自己搞的话,可以参考论坛置顶帖V5,V6,V7网盘的出厂程序,里面有个BMP格式文件保存方法,裸机UI的玩法, ...

你好,我没找到对应的工程目录,方便给个路径吗?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116197
QQ
发表于 4 天前 | 显示全部楼层
extero 发表于 2025-6-4 11:01
你好,我没找到对应的工程目录,方便给个路径吗?

以V5出厂程序为例,在这个文件里面

123.png

[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*
*	模块名称 : BMP文件处理模块
*	文件名称 : bmp_file.c
*	版    本 : V1.0
*	说    明 : 主要实现将屏幕截图保存为BMP文件
*
*	修改记录 :
*		版本号  日期        作者     说明
*		V1.0    2013-03-01 armfly  正式发布
*
*	Copyright (C), 2013-2014, 安富莱电子 [url]www.armfly.com[/url]
*
*********************************************************************************************************
*/

#include "ff.h"
#include "bmp_file.h"

/*
	BMP文件的组成结构 :

	位图文件头(bitmap-file header)
	位图信息头(bitmap-information header)
	彩色表/调色板(color table)
	位图数据(bitmap-data)

	如果图像是单色、16色和256色,则紧跟着调色板的是位图数据,位图数据是指向调色板的索引序号。
	如果位图是16位、24位和32位色,则图像文件中不保留调色板,即不存在调色板,图像的颜色直接在位图数据中给出。
	16位图像使用2字节保存颜色值,常见有两种格式:
		5位红 5位绿 5位蓝 即555格式。555格式只使用了15 位,最后一位保留,设为0。
		5位红 6位绿 5位蓝 即565格式。
	24位图像使用3字节保存颜色值,每一个字节代表一种颜色,按红、绿、蓝排列。
	32位图像使用4字节保存颜色值,每一个字节代表一种颜色,除了原来的红、绿、蓝,还有Alpha通道,即透明色。

*/

/* BMP文件头结构 必须添加__packed关键字表示结构体成员间紧密排列 */
__packed typedef struct
{
	/* 14字节 位图文件头 */
	uint16_t bfType;		/* 2字节 位图类别, 在Windows中,此字段的值总为'BM'*/
	uint32_t bfSize;		/* bmp文件大小 4字节 */
	uint16_t bfReserved1;	/* 保留,每字节以"00"填写 2字节 */
	uint16_t bfReserved2; 	/* 同上 2字节 */
	uint32_t bfOffBits;		/* 记录图像数据区的起始位置(图象数据相对于文件头字节的偏移量)。 4字节 */

	/* 40字节 位图信息头 */
	uint32_t biSize;		/* 4字节 本结构的大小,在Windows中,总为28h,40字节 */
	int32_t  biWidth;		/* 4字节 BMP图像的宽度,单位像素 */
	int32_t  biHeight;		/* 4字节 BMP图像的高度,单位像素 */
	uint16_t biPlanes;		/* 2字节 目标设备的级别(色彩平面数),固定为1 */
	uint16_t biBitCount;	/* 2字节 BMP图像的色深,即一个像素用多少位表示。常见的有 1 4 8 16 24 32 */
	uint32_t biCompression;	/* 4字节 压缩类型,0(不压缩), 1(BI_RLE8), 2(BI_RLE4) */
	uint32_t biSizeImage;	/* 4字节 表示位图数据区域的大小以字节为单位 */
	int32_t  biXPelsPerMeter;	/* 4字节 用象素/米表示的水平分辨率 */
	int32_t  biYPelsPerMeter;	/* 4字节 用象素/米表示的垂直分辨率 */
	uint32_t biClrUsed;			/* 4字节 实际使用色彩数目,则由位数定 */
	uint32_t biClrImportant;	/* 4字节 图像中重要的色彩数目。0表示调色板内所有的颜色都是重要的  */
}BMP_T;

/*
*********************************************************************************************************
*	函 数 名: MakeBmpHeader
*	功能说明: 生成BMP文件头结构。 固定按24位色, RGB = 888 结构。存储低字节在前,B前,G中,R后
*	形    参: _pBmp : BMP文件头结构体指针
*			 _Height : 图像高度
*			 _Width :  图像宽度
*	返 回 值: 无
*********************************************************************************************************
*/
//static void MakeBmpHeader(__packed BMP_T *_pBmp, uint16_t _Width, uint16_t _Height)
static void MakeBmpHeader(BMP_T *_pBmp, uint16_t _Width, uint16_t _Height)
{
	/* 14字节 位图文件头 */
	_pBmp->bfType = 0x4D42;	/* 2字节 位图类别, 在Windows中,此字段的值总为'BM'*/
	_pBmp->bfSize = (_Height * _Width * 3) + 54;	/* bmp文件大小 4字节 */
	_pBmp->bfReserved1 = 0;	/* 保留,每字节以"00"填写 2字节 */
	_pBmp->bfReserved2 = 0; /* 同上 2字节 */
	_pBmp->bfOffBits = 54;	/* 记录图像数据区的起始位置(图象数据相对于文件头字节的偏移量)。 4字节 */

	/* 40字节 位图信息头 */
	_pBmp->biSize = 40;		/* 4字节 本结构的大小,在Windows中,总为28h,40字节 */
	_pBmp->biWidth = _Width;/* 4字节 BMP图像的宽度,单位像素 */
	_pBmp->biHeight = _Height;		/* 4字节 BMP图像的高度,单位像素 */
	_pBmp->biPlanes = 1;			/* 2字节 目标设备的级别(色彩平面数),固定为1 */
	_pBmp->biBitCount = 24;			/* 2字节 BMP图像的色深,即一个像素用多少位表示。常见的有 1 4 8 16 24 32 */
	_pBmp->biCompression = 0;		/* 4字节 压缩类型,0(不压缩), 1(BI_RLE8), 2(BI_RLE4) */
	_pBmp->biSizeImage = (_Height * _Width * 3);	/* 4字节 表示位图数据区域的大小以字节为单位 */
	_pBmp->biXPelsPerMeter = 0;	/* 4字节 用象素/米表示的水平分辨率 */
	_pBmp->biYPelsPerMeter = 0;	/* 4字节 用象素/米表示的垂直分辨率 */
	_pBmp->biClrUsed = 0;		/* 4字节 实际使用色彩数目,0则由位数定 */
	_pBmp->biClrImportant = 0;	/* 4字节 图像中重要的色彩数目。0表示调色板内所有的颜色都是重要的  */
}

/*
*********************************************************************************************************
*	函 数 名: SaveScreenToBmp
*	功能说明: 将当前屏幕保存为BMP文件头。结合FatFS文件系统使用。
*	形    参: _index : 文件序号
*	返 回 值: 无
*********************************************************************************************************
*/
void SaveScreenToBmp(uint16_t _index)
{
	__packed BMP_T tBmpHead;
	uint8_t LineData[800 * 3]; 	/* 按最大 800像素宽度分配缓冲区 */
	uint16_t i,j;
	uint16_t pixel;

	/* 本函数使用的局部变量占用较多,请修改启动文件,保证堆栈空间够用 */
	FRESULT result;
	FATFS fs;
	FIL file;
	uint32_t bw;
	char path[32];

	bsp_LedOn(1);	/* 点亮LED1, 表示开始截屏 */

	MakeBmpHeader(&tBmpHead, LCD_GetWidth(), LCD_GetHeight());	/* 构建BMP文件头 */

	/* 文件系统操作 */
	{
		/* 挂载文件系统 */
		result = f_mount(&fs, FS_VOLUME_SD, 0);			/* Mount a logical drive, 1表示立即执行 */
		if (result != FR_OK)
		{
			goto quit1;
		}

		/* 打开文件 */
		sprintf(path, "%s/%dx%d_%02d.bmp", FS_VOLUME_SD, tBmpHead.biWidth, tBmpHead.biHeight, _index);
		//result = f_opendir(&DirInf, path);
		result = f_open(&file, path, FA_CREATE_ALWAYS | FA_WRITE);
		if (result != FR_OK)
		{
			printf("创建SD卡文件%s失败 (%d)\r\n", path, result);
			goto quit1;
		}
	}

	/* 写bmp文件头 */
	result = f_write(&file, (char *)&tBmpHead, 54, &bw);
	if (result != FR_OK)
	{
		printf("%s 文件写入失败\r\n", path);
		goto quit1;
	}

	/* 开始读取屏幕数据,并写入文件 */
	for (i = 0; i <  tBmpHead.biHeight; i++)
	{
		/* 读取1行数据到缓冲区 (注意:BMP文件扫描次序,从左到右,从下到上。和LCD逻辑坐标是垂直翻转的) */
		for (j = 0; j < tBmpHead.biWidth; j++)
		{
			pixel = LCD_GetPixel(j, tBmpHead.biHeight - i - 1);		/* 读取屏幕1个像素 (RGB = 565结构)*/
			
			#if 1
			LineData[3 * j + 2] = ((pixel & 0xF800) >> 8);		/* R */
			LineData[3 * j + 1] = ((pixel & 0x07E0) >> 3);		/* G */
			LineData[3 * j + 0] = ((pixel & 0x001F) << 3);		/* B */
			#else
			if (_index == 0)
			{
				LineData[3 * j + 2] = 255;
				LineData[3 * j + 1] = 0;
				LineData[3 * j + 0] = 0;
			}
			else if (_index == 1)
			{
				LineData[3 * j + 2] = 0;
				LineData[3 * j + 1] = 255;
				LineData[3 * j + 0] = 0;
			}
			else
			{
				LineData[3 * j + 2] = 0;
				LineData[3 * j + 1] = 0;
				LineData[3 * j + 0] = 255;
			}			
			#endif
		}

		#if 0
		/* 写1行数据 */
		result = f_write(&file, LineData, tBmpHead.biWidth * 3, &bw);
		if (result != FR_OK)
		{
			printf("%s 文件写入失败\r\n", path);
			goto quit1;
		}
		#else
		
		for (j = 0 ;j < tBmpHead.biWidth * 3 / 480; j++)
		{
			/* 写1行数据 */
			result = f_write(&file, &LineData[480 * j], 480, &bw);
			if (result != FR_OK)
			{
				printf("%s 文件写入失败\r\n", path);
				goto quit1;
			}
		}		
		#endif
	}

quit1:
	/* 关闭文件*/
	f_close(&file);

	/* 卸载文件系统 */
	//f_mount(ucVolume, NULL);
	f_mount(NULL,FS_VOLUME_SD, 0);

	bsp_LedOff(1);	/* 关闭LED1, 表示开始截屏结束 */
}

/***************************** 安富莱电子 [url]www.armfly.com[/url] (END OF FILE) *********************************/

回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
发表于 4 天前 | 显示全部楼层
eric2013 发表于 2025-6-5 08:20
以V5出厂程序为例,在这个文件里面

好的,感谢
回复

使用道具 举报

2

主题

7

回帖

13

积分

新手上路

积分
13
发表于 4 天前 | 显示全部楼层
eric2013 发表于 2025-6-5 08:20
以V5出厂程序为例,在这个文件里面

你好,我没找到这个出厂程序,不是在首页>产品服务>STM32F429板块中的置顶帖中吗?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116197
QQ
发表于 3 天前 | 显示全部楼层
extero 发表于 2025-6-5 10:47
你好,我没找到这个出厂程序,不是在首页>产品服务>STM32F429板块中的置顶帖中吗?

标准库网盘

https://www.armbbs.cn/forum.php?mod=viewthread&tid=1285
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-6-9 19:47 , Processed in 0.324157 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表