STM32 - EMWIN BMP picture display (22)

EMWI

1. Supported formats

emWin supports BMP image decoding, can directly read BMP image files from external storage (such as SD card) and display BMP image files on LCD The
BMP file format is defined by Microsoft
insert image description here

2. BMP file API function

GUI_BMP_Draw() 绘制已加载到存储器的 BMP 文件。
GUI_BMP_DrawEx() 绘制无需加载到存储器的 BMP 文件。
GUI_BMP_DrawScaled() 绘制已加载到存储器的带比例的 BMP 文件。
GUI_BMP_DrawScaledEx() 绘制无需加载到存储器的带比例的 BMP 文件。
GUI_BMP_GetXSize() 返回加载到存储器的 BMP 文件的 X 大小。
GUI_BMP_GetXSizeEx() 返回无需加载到存储器的 BMP 文件的 X 大小。
GUI_BMP_GetYSize() 返回加载到存储器的位图的 Y 大小。
GUI_BMP_GetYSizeEx() 返回无需加载到存储器的 Y 大小。
GUI_BMP_Serialize() 创建 BMP 文件。
GUI_BMP_SerializeEx() 基于给定的矩形创建 BMP 文件。

3. Experimental code

#include "bmpdisplay.h"
#include "EmWinHZFont.h"
#include "GUI.h"
#include "malloc.h"
#include "ff.h"
#include "ili93xx.h"


#if SYSTEM_SUPPORT_UCOS
#include "includes.h"					//ucos ʹÓÃ	  
#endif

static FIL BMPFile;
static char bmpBuffer[BMPPERLINESIZE];

static int BmpGetData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off) 
{
    
    
	static int readaddress=0;
	FIL * phFile;
	UINT NumBytesRead;
	#if SYSTEM_SUPPORT_UCOS
		OS_CPU_SR cpu_sr;
	#endif
	
	phFile = (FIL *)p;
	
	if (NumBytesReq > sizeof(bmpBuffer)) 
	{
    
    
		NumBytesReq = sizeof(bmpBuffer);
	}

	//Òƶ¯Ö¸Õëµ½Ó¦¸Ã¶ÁÈ¡µÄλÖÃ
	if(Off == 1) readaddress = 0;
	else readaddress=Off;
	#if SYSTEM_SUPPORT_UCOS
		OS_ENTER_CRITICAL();	//ÁÙ½çÇø
	#endif
	f_lseek(phFile,readaddress); 
	
	//¶ÁÈ¡Êý¾Ýµ½»º³åÇøÖÐ
	f_read(phFile,bmpBuffer,NumBytesReq,&NumBytesRead);
	#if SYSTEM_SUPPORT_UCOS
		OS_EXIT_CRITICAL();	//Í˳öÁÙ½çÇø 
	#endif
	*ppData = (U8 *)bmpBuffer;
	return NumBytesRead;//·µ»Ø¶ÁÈ¡µ½µÄ×Ö½ÚÊý
}

//ÔÚÖ¸¶¨Î»ÖÃÏÔʾÎÞÐè¼ÓÔص½RAMÖеÄBMPͼƬ(ÐèÎļþϵͳ֧³Ö£¡¶ÔÓÚСRAM£¬ÍƼöʹÓô˷½·¨£¡)
//BMPFileName:ͼƬÔÚSD¿¨»òÕßÆäËû´æ´¢É豸ÖеÄ·¾¶
//mode:ÏÔʾģʽ
//		0 ÔÚÖ¸¶¨Î»ÖÃÏÔʾ£¬ÓвÎÊýx,yÈ·¶¨ÏÔʾλÖÃ
//		1 ÔÚLCDÖмäÏÔʾͼƬ£¬µ±Ñ¡Ôñ´ËģʽµÄʱºò²ÎÊýx,yÎÞЧ¡£
//x:ͼƬ×óÉϽÇÔÚLCDÖеÄxÖáλÖÃ(µ±²ÎÊýmodeΪ1ʱ£¬´Ë²ÎÊýÎÞЧ)
//y:ͼƬ×óÉϽÇÔÚLCDÖеÄyÖáλÖÃ(µ±²ÎÊýmodeΪ1ʱ£¬´Ë²ÎÊýÎÞЧ)
//member:  Ëõ·Å±ÈÀýµÄ·Ö×ÓÏî
//denom:Ëõ·Å±ÈÀýµÄ·ÖĸÏî
//·µ»ØÖµ:0 ÏÔʾÕý³£,ÆäËû ʧ°Ü
int dispbmpex(u8 *BMPFileName,u8 mode,u32 x,u32 y,int member,int denom)
{
    
    
	char result;
	int XSize,YSize;
	float Xflag,Yflag;
	GUI_COLOR forecolor,bkcolor;
	forecolor=GUI_GetColor();			//»ñÈ¡µ±Ç°Ç°¾°É«
	bkcolor=GUI_GetBkColor();			//»ñÈ¡µ±Ç°±³¾°É«
	
	result = f_open(&BMPFile,(const TCHAR*)BMPFileName,FA_READ);	//´ò¿ªÎļþ
	//Îļþ´ò¿ª´íÎó
	if(result != FR_OK) 	return 1;
		
	switch(mode)
	{
    
    
		case 0:	//ÔÚÖ¸¶¨Î»ÖÃÏÔʾͼƬ
			if((member == 1) && (denom == 1)) //ÎÞÐèËõ·Å£¬Ö±½Ó»æÖÆ
			{
    
    
				GUI_BMP_DrawEx(BmpGetData,&BMPFile,x,y);//ÔÚÖ¸¶¨Î»ÖÃÏÔʾBMPͼƬ
			}else //·ñÔòͼƬÐèÒªËõ·Å
			{
    
    
				GUI_BMP_DrawScaledEx(BmpGetData,&BMPFile,x,y,member,denom);
			}
			break;
		case 1:	//ÔÚLCDÖмäÏÔʾͼƬ
			XSize = GUI_BMP_GetXSizeEx(BmpGetData,&BMPFile);	//»ñȡͼƬµÄXÖá´óС
			YSize = GUI_BMP_GetYSizeEx(BmpGetData,&BMPFile);	//»ñȡͼƬµÄYÖá´óС
			if((member == 1) && (denom == 1)) //ÎÞÐèËõ·Å£¬Ö±½Ó»æÖÆ
			{
    
    
				//ÔÚLCDÖмäÏÔʾͼƬ
				GUI_BMP_DrawEx(BmpGetData,&BMPFile,(lcddev.width-XSize)/2-1,(lcddev.height-YSize)/2-1);
			}else //·ñÔòͼƬÐèÒªËõ·Å
			{
    
    
				Xflag = (float)XSize*((float)member/(float)denom);
				Yflag = (float)YSize*((float)member/(float)denom);
				XSize = (lcddev.width-(int)Xflag)/2-1;
				YSize = (lcddev.height-(int)Yflag)/2-1;
				GUI_BMP_DrawScaledEx(BmpGetData,&BMPFile,XSize,YSize,member,denom);
			}
			break;
	}
	f_close(&BMPFile);		//¹Ø±ÕBMPFileÎļþ
	GUI_SetColor(forecolor);		//»Ö¸´Ç°¾°É«
	GUI_SetBkColor(bkcolor);		//»Ö¸´±³¾°É«
	return 0;
}

//´Ëº¯Êý±»GUI_BMP_Serialize()µ÷Óã¬ÓÃÀ´ÏòÎļþдÈë×Ö½Ú
static void _WriteByte2File(U8 Data, void * p) 
{
    
    
	UINT nWritten;
	f_write((FIL*)p,&Data,1,&nWritten);
}

//Éú³ÉÒ»¸öBMPͼƬ£¬±£´æµ½SD¿¨ÖÐ,ʵÏÖÆÁÄ»½Øͼ¹¦ÄÜ£¡
//*filepath:Îļþ·¾¶
//x0:´´½¨BMPÎļþµÄXÆðʼλÖÃ
//y0:´´½¨BMPÎļþµÄYÆðʼλÖÃ
//Xsize:XµÄ´óС
//Ysize:YµÄ´óС
void create_bmppicture(u8 *filename,int x0,int y0,int Xsize,int Ysize)
{
    
    
	static FIL hFile;
	GUI_COLOR forecolor,bkcolor;
	forecolor=GUI_GetColor();		//»ñÈ¡µ±Ç°Ç°¾°É«
	bkcolor=GUI_GetBkColor();		//»ñÈ¡µ±Ç°±³¾°É«
	//´´½¨Ò»¸öÎļþ£¬Â·¾¶Îªfilename,Èç¹ûÎļþÔ­±¾¾Í´æÔڵĻ°»á±»Ð½¨µÄÎļþ¸²¸Çµô£¡
	f_open(&hFile,(const TCHAR*)filename,FA_READ|FA_WRITE|FA_CREATE_ALWAYS);
	GUI_BMP_SerializeEx(_WriteByte2File,x0,y0,Xsize,Ysize,&hFile);
	f_close(&hFile);	//¹Ø±ÕÎļþ
	GUI_SetColor(forecolor);		//»Ö¸´Ç°¾°É«
	GUI_SetBkColor(bkcolor);		//»Ö¸´±³¾°É«
}	

void bmpdisplay_demo(void)
{
    
    
	GUI_SetBkColor(GUI_BLUE);
	GUI_SetColor(GUI_RED);
	GUI_SetFont(&GUI_FontHZ16);
	GUI_Clear();
	
	while(1)
	{
    
    
		GUI_DispStringHCenterAt("ÔÚÖ¸¶¨Î»ÖÃÏÔʾһÕÅÎÞÐè¼ÓÔصÄBMPͼƬ",400,5);
		dispbmpex("0:/PICTURE/BMP/ALIENTEKLOGO.bmp",0,10,	78,	1,1);
		GUI_Delay(1000);
		GUI_Clear();
	
	
		GUI_DispStringHCenterAt("ÔÚLCDÖмäÏÔʾһÕÅËõС1/2µÄÎÞÐè¼ÓÔصÄBMPͼƬ",400,5);
		dispbmpex("0:/PICTURE/BMP/ALIENTEKLOGO.bmp",1,0,	0,	1,2);
		GUI_Delay(1000);
		GUI_Clear();
	
		GUI_DispStringHCenterAt("ÔÚLCDÖмäÏÔʾһÕÅÀ©´ó4/3±¶µÄÎÞÐè¼ÓÔصÄBMPͼƬ",400,5);
		dispbmpex("0:/PICTURE/BMP/ALIENTEKLOGO.bmp",1,0,	0,	4,3);
		GUI_Delay(1000);
		GUI_Clear();
	}
}

BmpGetData() 从外部存储器获取 BMP 文件数据
dispbmp()
将 BMP 图片加载到 RAM 中,并显示到 LCD 上,显示速度快,但是需要大量的 RAM。 dispbmpex() 不需要将 BMP 加载到 RAM 中,显示速度慢,但是不需要大量的 RAM。
_WriteByte2File() 由函数 GUI_BMP_Serialize()调用,用于向文件写入数据。
create_bmppicture() 屏幕截图函数

insert image description here

Guess you like

Origin blog.csdn.net/qq_51963216/article/details/124079538