本帖最后由 hpdell 于 2018-5-29 11:08 编辑
请教下,使用 GUI_MEMDEV_Rotate 旋转显示表盘指针图片 ?
使用函数 GUI_MEMDEV_Rotate ,图片旋转始终都是以图片的中心为基准的,有没有什么方法可以改一下啊 ?
另外,指针图片是不是需要做成 镜像的图片 ,吧镜像部分搞成透明 ??????
效果如下:
旋转图片-2.jpg (40.87 KB, 下载次数: 0)
下载附件
2018-5-29 09:32 上传
显示代码如下:
void GUI_MEMDEV_ColckRotaeShow(void)
{
int t0; // 用于三个指针的计数
int t1;
int t2;
GUI_MEMDEV_Select(hMemDest);
GUI_MEMDEV_Write (hMemLcd); //将给定存储设备的内容写入当前选定的存储设备中,
GUI_MEMDEV_Rotate(hMemSourceBk,
hMemDest,
0, // 显示地址由 hMemDest、hMemLcd 决定
0, // 显示地址由 hMemDest、hMemLcd 决定
0, // 因为显示表盘不需要旋转,所以此次的值为0
1000);
// 第一个指针计数,用于旋转秒针
t0 = 360 - (RotateSecond * 6);
// 第二个指针计数,用于旋转分针
t1 = 360 - (RotateMinute *6) -(RotateSecond /10); //秒针每移动10秒,分钟移动的角度为1度
/*
把小时 sTime.Hours%12是吧24小时制式sTime.Hours转化为12小时制,*30(因为小时时针每小时运行30度),
((sTime.Minutes /10)*6) 这句是分钟每移动10分钟,小时时针移动 6度
*/
t2 = 360 - (((RotateHour)%12) * 30) - ((RotateMinute /10)*6);
GUI_MEMDEV_RotateHQ(hMemHour,
hMemDest,
100+56, // (RectDest.x1 - RectSource.x1) / 2,
83, //(RectDest.y1 - RectSource.y1) / 2,
t2 * 1000,
1000);
GUI_MEMDEV_RotateHQ(hMemMinute,
hMemDest,
100+56, // (RectDest.x1 - RectSource.x1) / 2,
43, //(RectDest.y1 - RectSource.y1) / 2,
t1 * 1000,
1000);
GUI_MEMDEV_RotateHQ(hMemSecond,
hMemDest,
100+59, // (RectDest.x1 - RectSource.x1) / 2,
174/4+32, //(RectDest.y1 - RectSource.y1) / 2,
t0 * 1000,
1000);
GUI_MEMDEV_Select(0);
GUI_MULTIBUF_Begin();
GUI_MEMDEV_CopyToLCD (hMemDest);
GUI_MULTIBUF_End();
RotateSecond ++;
if(RotateSecond >= 60)
{
RotateSecond = 0;
RotateMinute++;
if(RotateMinute >= 60)
{
RotateMinute =0;
RotateHour++;
if(RotateHour >= 24)
{
RotateHour=0;
}
}
}
}
你好,最终修改了图片,
代码如下:
// 使用 流位图显示
//app图标描述结构体
typedef struct{
const char *pFileNamePath; // 图标文件名路径
} CLOCK_BITMAP_ITEM_STREAM;
/*
流数据取数据说明如下:
1. 先准备好需要的图标图片,*.bmp,*.png格式的,必须带透明通道的图片
2. 使用 st 提供的工具软件 BmpCvtST.exe (版本v532或v5.40都行) 打开已准备好的图片
3. 打开后什么也不修改直接 点击 Files->Save as ... 选择 *.dta 格式 按保存
4. a: 如果选择 True color with alpha 格式保存的,是按照 每个像素 4 字节取码的 +16Byte
b: 如果选择 High color with Alpha(565) 格式保存的,是按照 rgb565格式保存,另外还多了一个字节的透明通道数据
实际是按照 3字节保存数据 +16Byte
5. 比如一个图片像素为 96*96,那么按照 565格式取码后的大小为 96*3*96+16大小
*/
static const CLOCK_BITMAP_ITEM_STREAM ClockStreamBitmapItemTab1[]={
// 图片旋转 只支持 argb8888 格式,切记切记
"0:ClockSrteam/dta_ARGB8888/omega_367x332_SourceFile_ARGB8888.dta",
"0:ClockSrteam/dta_ARGB8888/HourCen_ARGB8888.dta",
"0:ClockSrteam/dta_ARGB8888/MinuteCen_ARGB8888.dta",
"0:ClockSrteam/dta_ARGB8888/SecondCen_ARGB8888.dta",
};
typedef struct
{
const int xSize;
const int ySize;
} _ClockPosStreamTypeDef;
const _ClockPosStreamTypeDef _ClockPosStream[]={
367, 332,
23, 166,
25, 244,
17, 268
};
typedef struct
{
GUI_MEMDEV_Handle hMem1_Clock[4]; // 时钟表盘、表针,数组0表示表盘背景,1表示时针,2表示分针,3表示秒针
GUI_MEMDEV_Handle hMem1_ClockDest; // 目标内存
GUI_MEMDEV_Handle hMem1_ClockLcd; // 显示内存
GUI_BITMAP Bitmap[4]; // 时钟表盘、表针,数组0表示表盘背景,1表示时针,2表示分针,3表示秒针
GUI_LOGPALETTE Palette[4];
uint8_t *_acComBuff ;
uint8_t *_acClockBuf[4] ; // 时钟表盘、表针,数组0表示表盘背景,1表示时针,2表示分针,3表示秒针
} _ClockPramTypeDef;
_ClockPramTypeDef * _ClockParm = NULL;
#define DEG2RAD_180 (float)((float)3.1415926f / 180) // 0.0174532924
#define MAG 3
/*
*********************************************************************************************************
* 函 数 名: InitDialogRTC
* 功能说明: 对话框回调函数的初始化消息
* 形 参: pMsg 消息指针变量
* 返 回 值: 无
*********************************************************************************************************
*/
void InitDialogRTC(void)
{
GUI_MEMDEV_RTC_ClockInit();
}
/*
函数名称:GUI_MEMDEV_RTC_ClockInit
函数功能:初始化内存设备,在GUI_Init 之后调用也可以在 WM_INIT_DIALOG 这个里面调用一次
初始化只执行一次即可
参数:无
返回值:无
*/
static void GUI_MEMDEV_RTC_ClockInit(void)
{
FIL CLOCK_File;
FRESULT result;
UINT bw;
int i=0;
if (BSP_SD_IsDetected() != SD_PRESENT)
{
printf((const char *)"RTC SD 卡不存在,请插入 ... ... ? ");
return ;
}
//此内存申请后就不释放了,因为程序一直在运行
_ClockParm = (_ClockPramTypeDef *)mymalloc(SRAMEX, sizeof(_ClockPramTypeDef) ); //SRAMDTCM
for(i=0;i<4;i++)
{
result = f_open(&CLOCK_File, ClockStreamBitmapItemTab1.pFileNamePath, FA_READ );
if (result != FR_OK)
{
printf("open file fail %d ",result );
myfree(SRAMEX,(void *) _ClockParm);
return;
}
_ClockParm->_acClockBuf = GUI_MYmalloc(CLOCK_File.obj.objsize );
_ClockParm->_acComBuff = _ClockParm->_acClockBuf;
result = f_read(&CLOCK_File, _ClockParm->_acComBuff, CLOCK_File.obj.objsize, &bw);
if (result != FR_OK)
{
__IO int cc;
for(cc=0;cc<i;cc++)
{
_ClockParm->_acComBuff = _ClockParm->_acClockBuf[cc];
GUI_MYfree((void *) _ClockParm->_acComBuff); //使用完后释放内存
}
f_close(&CLOCK_File);
myfree(SRAMEX,(void *) _ClockParm);
return ;
}
f_close(&CLOCK_File);
}
for(i=0;i<4;i++)
{
// 适用与 emwin > v5.32 argb / abgr 库 版本
// 显示表盘背景, 在单片机上绘制 32bit BMP 图片数据文件,必须使用GUI_MEMDEV_CreateFixed32 这个函数
// 图片旋转只支持 32bit 格式的图片,切记切记 2018.06.14 21:10
_ClockParm->hMem1_Clock = GUI_MEMDEV_CreateFixed32(0, //创建具有 32bpp 颜 {MOD}深度和 GUICC_8888 颜 {MOD}转换的内存设备
0,
_ClockPosStream.xSize,
_ClockPosStream.ySize );
GUI_MEMDEV_Select(_ClockParm->hMem1_Clock);
_ClockParm->_acComBuff = _ClockParm->_acClockBuf;
GUI_SetBkColor(GUI_TRANSPARENT ); //清除背景 {MOD} 0xFFC0C0C0 GUI_TRANSPARENT
GUI_Clear();
GUI_CreateBitmapFromStream(&_ClockParm->Bitmap, &_ClockParm->Palette, _ClockParm->_acComBuff);
GUI_DrawBitmap(&_ClockParm->Bitmap, 0, 0);
}
_ClockParm->hMem1_ClockDest = GUI_MEMDEV_CreateFixed32( 1024-367, //最终显示的 x 地址
24, //最终显示的 y 地址
_ClockPosStream[0].xSize, //与显示最大表盘尺寸宽度一致即可
_ClockPosStream[0].ySize );
_ClockParm->hMem1_ClockLcd = GUI_MEMDEV_CreateFixed32( 1024-367, //最终显示的 x 地址
24, //最终显示的 y 地址
_ClockPosStream[0].xSize, //与显示最大表盘尺寸宽度一致即可
_ClockPosStream[0].ySize );
//-----------------------------------------------------------------------------------------
GUI_MEMDEV_Select(0);
GUI_MEMDEV_CopyFromLCD (_ClockParm->hMem1_ClockLcd); //将 LCD 内容复制到存储设备
// 释放申请内存
for(i=0;i<4;i++)
{
_ClockParm->_acComBuff = _ClockParm->_acClockBuf;
GUI_MYfree((void *) _ClockParm->_acComBuff); //使用完后释放内存
}
// myfree(SRAMEX,(void *) _ClockParm); //这个 _ClockParm 参数不能够释放,因为程序一直在运行
/* 配置回之前选择的目标窗口 */
// WM_SelectWindow(hWinOld);
}
/*
*********************************************************************************************************
* 函 数 名: Clock_DrawDisp
* 功能说明: 更新时钟表盘
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void Clock_DrawDisp(WM_MESSAGE * pMsg)
{
int t0; // 用于三个指针的计数
int t1;
int t2;
char buf[30];
WM_HWIN hWin = pMsg->hWin;
// Get the RTC current Time
HAL_RTC_GetTime(&RtcHandle, &sTime, RTC_FORMAT_BIN); // 时间与日期需要同时获取,切记切记,
// Get the RTC current Date
HAL_RTC_GetDate(&RtcHandle, &sDate, RTC_FORMAT_BIN);
t0 = 360 - (sTime.Seconds * 6); // 第一个指针计数,用于旋转秒针
// 第二个指针计数,用于旋转分针
t1 = 360 - (sTime.Minutes *6) -(sTime.Seconds /10); //秒针每移动10秒,分钟移动的角度为1度
/*
把小时 sTime.Hours%12是吧24小时制式sTime.Hours转化为12小时制,*30(因为小时时针每小时运行30度),
((sTime.Minutes /10)*5) 这句是分钟每移动10分钟,小时时针移动 5度
*/
t2 = 360 - (((sTime.Hours)%12) * 30) - ((sTime.Minutes /10)*5);
GUI_MEMDEV_Select(_ClockParm->hMem1_ClockDest);
GUI_MEMDEV_Write (_ClockParm->hMem1_ClockLcd); //将给定存储设备的内容写入当前选定的存储设备中,
//即hMem1_ClockLcd -> hMem1_ClockDest
GUI_BMP_ShowBkPicture(); // 使用 emwin v5.40 abgr 版本,需要在此处重新绘制一下背景 {MOD},否则表盘不会显示透明功能
// 如果使用单 {MOD}背景 {MOD},则此处不需要,但需要吧 GUI_CreateBitmapFromStream 此函数
// 之前屏蔽的函数打开即可,切记切记 2018.07.05 sws
GUI_MEMDEV_Rotate(_ClockParm->hMem1_Clock[0],
_ClockParm->hMem1_ClockDest,
0, // 显示地址由 hMemDest、hMemLcd 决定
0, // 显示地址由 hMemDest、hMemLcd 决定
0, // 因为显示表盘不需要旋转,所以此次的值为0
1000);
GUI_MEMDEV_Rotate(_ClockParm->hMem1_Clock[1],
_ClockParm->hMem1_ClockDest,
157, // 显示时针计算方法,表盘的中心x坐标-时针的中心x坐标,偏移量
//已经在创建时设定好的,也就是以创建时的坐标为基准
83,
t2 * 1000,
1000);
GUI_MEMDEV_Rotate(_ClockParm->hMem1_Clock[2],
_ClockParm->hMem1_ClockDest,
156,
44,
t1 * 1000,
1000);
GUI_MEMDEV_Rotate(_ClockParm->hMem1_Clock[3],
_ClockParm->hMem1_ClockDest,
161,
32 ,
t0 * 1000,
1000);
GUI_MEMDEV_Select(0);
GUI_MULTIBUF_Begin();
GUI_MEMDEV_CopyToLCD (_ClockParm->hMem1_ClockDest); //将内容显示到 LCD 屏幕上
GUI_MULTIBUF_End();
/* 更新 表盘里面的 星期 */
sprintf(buf,
"%s",
RtcWeek[sDate.WeekDay]);
TEXT_SetText(WM_GetDialogItem(hWin, GUI_ID_TEXT2), buf);
/* 更新 表盘里面的 日期 */
sprintf(buf,
"%s",
apDaysRiQi[sDate.Date-1]);
TEXT_SetText(WM_GetDialogItem(hWin, GUI_ID_TEXT3), buf);
}
一周热门 更多>