STemWin显示图片

目录

一  通过BmpCvtST.exe软件将图片转换为C数组,然后通过GUI_DrawBitmapEx函数显示

二  STemWin中bmp,jpg,gif,png格式图片的相关接口函数

三  读取SD卡的BMP格式图片的数据,然后调用GUI_BMP_DrawEx函数BMP图片。

四 读取SD卡的JPG格式图片的数据,然后调用GUI_JPG_DrawEx函数JPG图片。

五 读取SD卡的GIF格式图片的数据,然后调用GUI_GIF_DrawSub函数GIF图片。


一  通过BmpCvtST.exe软件将图片转换为C数组,然后通过GUI_DrawBitmapEx函数显示

该方式比较简便且可以转换多种图片格式,但是比较耗内存,生成的图片数组会占用大量空间。

1. 通过BmpCvtST.exe软件打开一张图片,然后通过“Image->Convert to->Best palette转换图片”

2. 通过“File -> save as”菜单将图片保存为.c文件,然后选择“8 bit per pixel ”或者 “High color(565)”都行

3. 生成的.c文件格式如下所示,需要关注的是bmzhenji_bitmap 结构体:

extern GUI_CONST_STORAGE GUI_BITMAP bmzhenji_bitmap;

static GUI_CONST_STORAGE unsigned short _aczhenji_bitmap[] = {
	...............................//此处省略
  };

GUI_CONST_STORAGE GUI_BITMAP bmzhenji_bitmap = {
  500, // xSize
  346, // ySize
  1000, // BytesPerLine
  16, // BitsPerPixel
  (unsigned char *)_aczhenji_bitmap,  // Pointer to picture data
  NULL,  // Pointer to palette
  GUI_DRAW_BMP565
};

4. 通过GUI_DrawBitmapEx函数显示图片,该函数使用方法如下

//位图中坐标为(0,0)的对应显示在LCD的(150,30)点,且缩放倍数为500/1000 = 0.5
    GUI_DrawBitmapEx(&bmzhenji_bitmap, 150, 30, 0, 0, 500, 500);

二  STemWin中bmp,jpg,gif,png格式图片的相关接口函数

BMP格式BMP格式图片的所有数据都已加载入内存(数组)时,可调用的相关函数。(使用该方式需要分配一个与图片大小一样的内存空间,且需要GUI_ALLOC_AssignMemory函数分配的STemWin空间能够完全加载整个图片,比较耗内存。)

GUI_BMP_GetXSize()      //获取图片X方向尺寸

GUI_BMP_GetYSize()      //获取图片Y方向尺寸

GUI_BMP_Draw()             //按原大小进行显示

GUI_BMP_DrawScaled()  //进行倍数显示

BMP格式图片循环读入一块指定大小的内存中,进行显示时,可调用的相关函数。(该方式必须额外实现一个GUI_GET_DATA_FUNC类型的函数)

GUI_BMP_GetXSizeEx()  //获取图片X方向尺寸

GUI_BMP_GetYSizeEx()  //获取图片Y方向尺寸

GUI_BMP_DrawEx()         //按原大小进行显示

GUI_BMP_DrawScaledEx()//进行倍数显示

将LCD屏幕截图为BMP格式的图片,可调用的相关函数

GUI_BMP_Serialize() 

GUI_BMP_SerializeEx()

GUI_BMP_SerializeExBpp()

JPG格式JPG格式图片的所有数据都已加载入内存(数组)时,可调用的相关函数。

GUI_JPEG_GetInfo()

GUI_JPEG_Draw() 

GUI_JPEG_DrawScaled()

JPGP格式图片循环读入一块指定大小的内存中,进行显示时,可调用的相关函数。

GUI_JPEG_DrawEx() 

GUI_JPEG_DrawScaledEx()

GUI_JPEG_GetInfoEx()

GIF格式GIF格式图片的所有数据都已加载入内存(数组)时,可调用的相关函数。(如果是动图,建议使用该种方式)

GUI_GIF_GetImageInfo()//获取图片信息

GUI_GIF_Draw()//显示gif中的第一张图片

GUI_GIF_DrawSub()//第一张图片按倍数关系显示

GUI_GIF_DrawSub()//显示gif中的子图片

GUI_GIF_DrawSubScaled()//子图片按倍数关系显示

GIF格式图片循环读入一块指定大小的内存中,进行显示时,可调用的相关函数。(如果是动图,在STemWin中使用该种方式显示会发现越来越慢,猜测越到后面通过GUI_GET_DATA_FUNC函数读取数据越慢,具体原因不详。)

GUI_GIF_GetImageInfoEx()//获取图片信息

GUI_GIF_DrawEx()//显示gif中的第一张图片

GUI_GIF_DrawSubEx()//第一张图片按倍数关系显示

GUI_GIF_DrawSubEx()//显示gif中的子图片

GUI_GIF_DrawSubScaledEx()//子图片按倍数关系显示

PNG格式PNG格式图片的所有数据都已加载入内存(数组)时,可调用的相关函数。(默认STemWin不带PNG相关函数,需要管网下载添加额外的PNG库)

GUI_PNG_GetXSize() 

GUI_PNG_GetYSize()

GUI_PNG_Draw()

PNG格式图片循环读入一块指定大小的内存中,进行显示时,可调用的相关函数。

GUI_PNG_GetXSizeEx() 

GUI_PNG_GetYSizeEx()

GUI_PNG_DrawEx()

三  读取SD卡的BMP格式图片的数据,然后调用GUI_BMP_DrawEx函数BMP图片。

通过查看GUI_BMP_DrawEx函数,发现期第一个参数为GUI_GET_DATA_FUNC 类型的指针,而该指针定义如下:
typedef int GUI_GET_DATA_FUNC(void * p, const U8 ** ppData, unsigned NumBytes, U32 Off);
在STemWin的官方手册会说明该函数该怎么设计,下面是通过Fat32文件系统读取文件数据的前提下设计的该函数,该函数也通用于jpg,png,gif图片格式的显示。

//绘制无需加载到RAM中的BMP图片时,图片每行的字节数
#define BMP_PERLINE_SIZE	2*1024	
static char bmpBuffer[BMP_PERLINE_SIZE];
static int GetPicData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off) 
{
	static int readAddr = 0;
	FIL * phFile;
	UINT br;
	
	phFile = (FIL *)p;
	
	if (NumBytesReq > sizeof(bmpBuffer)) {
		NumBytesReq = sizeof(bmpBuffer);
	}

	//移动指针到应该读取的位置
	if(Off == 1) 
            readAddr = 0;
	else 
            readAddr = Off;

	f_lseek(phFile,readAddr);
	f_read(phFile, bmpBuffer, NumBytesReq, &br);//读取数据到缓冲区中

	*ppData = (U8 *)bmpBuffer;
    
	return br;//返回读取到的字节数
}

实现了GetPicData函数后,接下来就可以调用GUI_BMP_DrawEx函数进行显示了

static FIL PicFile;

/***************************************************************************************
  * @brief   
  * @input   BMPFileName:图片在SD卡或者其他存储设备中的路径(需文件系统支持!)
  * @return  
***************************************************************************************/
uint8_t ReadDisp_bmp(char *fileName)
{
    int XSize,YSize;
    
    /*######1. 打开bmp文件,判断文件大小#######*/
    retSD = f_open(&PicFile, (const TCHAR*)fileName, FA_READ);
    if(retSD != FR_OK || PicFile.obj.objsize > BMP_MAX_SIZE){
        return 1;
    }
    
    /*######2. 获取bmp图像尺寸#######*/
    XSize = GUI_BMP_GetXSizeEx(GetPicData, &PicFile);	//获取图片的X轴大小
    YSize = GUI_BMP_GetYSizeEx(GetPicData, &PicFile);	//获取图片的Y轴大小
    
    /*######3. 通过GUI_BMP_GetXSizeEx函数在LCD中间显示bmp图像#######*/
    GUI_BMP_DrawEx(GetPicData, &PicFile, (LCD_WIDTH-XSize)/2-1, (LCD_HEIGHT-YSize)/2-1);
    
    /*######4. 通过GUI_BMP_GetXSizeEx函数在LCD中间显示0.5倍的bmp图像#######*/
    GUI_BMP_DrawScaledEx(GetPicData, &PicFile, (LCD_WIDTH - XSize * 0.5)/2, (LCD_HEIGHT - YSize * 0.5)/2, 1, 2);
    
    f_close(&PicFile);
    
    return 0;
}

四 读取SD卡的JPG格式图片的数据,然后调用GUI_JPG_DrawEx函数JPG图片。

static FIL PicFile;

/***************************************************************************************
  * @brief   
  * @input   JPGFileName:图片在SD卡或者其他存储设备中的路径(需文件系统支持!)
  * @return  
***************************************************************************************/
uint8_t ReadDisp_jpg(char *FileName)
{
    GUI_JPEG_INFO JpegInfo;
    
    /*######1. 打开jpg文件,判断文件大小#######*/
    retSD = f_open(&PicFile, (const TCHAR*)FileName, FA_READ);
    if(retSD != FR_OK || PicFile.obj.objsize > BMP_MAX_SIZE){
        return 1;
    }
    
    /*######3. 在LCD中间显示jpg图像#######*/
    GUI_JPEG_DrawEx(GetPicData, &PicFile,(LCD_WIDTH-JpegInfo.XSize)/2, (LCD_HEIGHT-JpegInfo.YSize)/2);
    GUI_Delay(500);
    GUI_Clear();
    
    /*######4. 按0.5倍在LCD中间显示jpg图像#######*/
    GUI_JPEG_DrawScaledEx(GetPicData, &PicFile, (LCD_WIDTH - JpegInfo.XSize * 0.5)/2, (LCD_HEIGHT - JpegInfo.YSize * 0.5)/2, 1, 2);
    
    f_close(&PicFile);
    return 0;
}

五 读取SD卡的GIF格式图片的数据,然后调用GUI_GIF_DrawSub函数GIF图片。

ReadDisp_gif函数中的内存分配函数是自己实现的,分配的是SDRAM中的空间,具体实现方式可参考正点原子的例子。

代码中的mem_free与mem_malloc函数可参考博客https://blog.csdn.net/Ningjianwen/article/details/90940570中的第四小节

ReadDisp_gif函数如下所示:

static FIL PicFile;

/***************************************************************************************
  * @brief   
  * @input   FileName:图片在SD卡或者其他存储设备中的路径(需文件系统支持!)
  * @return  
***************************************************************************************/
uint8_t ReadDisp_gif(char *FileName)
{
    UINT br;
    char *bmpBuf;
    GUI_GIF_INFO       GifInfo;
    GUI_GIF_IMAGE_INFO ImageInfo;
    
    /*######1. 打开gif文件,判断文件大小#######*/
    retSD = f_open(&PicFile, (const TCHAR*)FileName, FA_READ);
    if(retSD != FR_OK || PicFile.obj.objsize > BMP_MAX_SIZE){
        return 1;
    }
    
    /*######2. 分配内存用于保存bmp文件内容#######*/
    bmpBuf = mem_malloc(PicFile.obj.objsize);
    if(bmpBuf == NULL){
        return 2;
    }
    
    /*######3. 将文件内容读入分配好的bmpBuf缓存#######*/
    retSD = f_read(&PicFile, bmpBuf, PicFile.obj.objsize, &br);
    if(retSD != FR_OK){
        return 3;
    }
    
    /*######4. 获取gif文件信息#######*/
    GUI_GIF_GetInfo(bmpBuf, PicFile.obj.objsize, &GifInfo);
    
    /*######5. 在LCD中间显示gif图像#######*/
    for(int i = 0; i < GifInfo.NumImages; i++)
    {
        GUI_GIF_DrawSub(bmpBuf, PicFile.obj.objsize, (LCD_WIDTH - GifInfo.xSize)/2, (LCD_HEIGHT - GifInfo.ySize)/2,i);
        GUI_Delay(ImageInfo.Delay ? ImageInfo.Delay*10 : 100 );//延时
    }
    
    /*######6. 按0.5倍关系在LCD中间显示gif图像#######*/
    for(int i=0; i < GifInfo.NumImages; i++)
    {
        GUI_GIF_DrawSubScaled(bmpBuf, PicFile.obj.objsize, (LCD_WIDTH - GifInfo.xSize * 0.5)/2, (LCD_HEIGHT - GifInfo.ySize * 0.5)/2, i, 1 ,2);
        GUI_Delay(ImageInfo.Delay ? ImageInfo.Delay*10 : 100 );//延时
    }
    
    mem_free(bmpBuf);
    f_close(&PicFile);
    return 0;
}

 

 

  • 0
    点赞
  • 6
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:黑客帝国 设计师:我叫白小胖 返回首页
评论

打赏作者

Ningjianwen

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值