UCGUI在16位LCD上如何实现渐变色显示效果?
本帖最后由 electrlife 于 2013-3-9 23:08 编辑如题所示,最近想把界面做的好看些,于是似着在UCGUI上实现一个渐变色的函数,如下所示:
一个是常规实现方式,另一个是优化的方式。
如果24位的LCD上显示没问题,可是如果在16位的LCD显示,则不是很理想。因此需要使用
类似Floyd-Steinberg算法的来消除影响。不知各位做过没,效果如何,速度如何,类似单
片机即CORTEX-M3这种MCU在UCGUI环境下使用是否可以流畅显示。
不知大家还有没有其它的方法!
#include "GUI_Protected.h"
typedef void tfDrawLine(int x, int y, int z);
/*********************************************************************
*
* Static code
*
**********************************************************************
*/
/*********************************************************************
*
* _DrawGradient
*
*/
#if 1
static void _DrawGradient(int x0, int y0, int x1, int y1, GUI_COLOR Color0, GUI_COLOR Color1,
const tfDrawLine *pfDrawLine, int Vertical) {
GUI_COLOR Color, OldColor;
int i, r0, g0, b0, r1, g1, b1, r, g, b;
int dt;
if (Vertical) {
dt = y1 - y0 + 1;
} else {
dt = x1 - x0 + 1;
}
r0 = (Color0>>0) & 0xff;
g0 = (Color0>>8) & 0xff;
b0 = (Color0>> 16) & 0xff;
r1 = (Color1>>0) & 0xff;
g1 = (Color1>>8) & 0xff;
b1 = (Color1>> 16) & 0xff;
OldColor = GUI_GetColor();
for (i = 0; i < dt; i++) {
r = r0 + (i * (r1 - r0)) / dt;
g = g0 + (i * (g1 - g0)) / dt;
b = b0 + (i * (b1 - b0)) / dt;
Color = r + (g << 8) + (b << 16);
LCD_SetColor(Color);
if (Vertical) {
/* void LCD_DrawHLine(int x0, int y,int x1) */
pfDrawLine(x0, y0+i, x1);
} else {
/* void LCD_DrawVLine(int x, int y0,int y1) */
pfDrawLine(x0+i, y0, y1);
}
}
LCD_SetColor(OldColor);
}
#else
static void _DrawGradient(int x0, int y0, int x1, int y1, GUI_COLOR Color0, GUI_COLOR Color1,
const tfDrawLine *pfDrawLine, int Vertical) {
int i, r0, g0, b0, r1, g1, b1, r, g, b;
int dt;
GUI_COLOR OldColor = GUI_GetColor();
r0 = (Color0>>0) & 0xff;
g0 = (Color0>>8) & 0xff;
b0 = (Color0>> 16) & 0xff;
r1 = (Color1>>0) & 0xff;
g1 = (Color1>>8) & 0xff;
b1 = (Color1>> 16) & 0xff;
if (Vertical) {
dt = y1 - y0 + 1;
y1 = y0;
} else {
dt = x1 - x0 + 1;
x1 = x0;
}
for (i = 0; i < dt; i++) {
r = r0 + (i * (r1 - r0)) / dt;
g = g0 + (i * (g1 - g0)) / dt;
b = b0 + (i * (b1 - b0)) / dt;
Color1 = r + (g << 8) + (b << 16);
if (Color1 != Color0) {
LCD_SetColor(Color0);
if (Vertical) {
if (y1 != y0) {
GUI_FillRect(x0, y0, x1, y1);
} else {
pfDrawLine(x0, y1, x1);
}
y1++;
y0 = y1;
} else {
if (x1 != x0) {
GUI_FillRect(x0, y0, x1, y1);
} else {
pfDrawLine(x1, y0, y1);
}
x1++;
x0 = x1;
}
Color0 = Color1;
} else {
if (Vertical) {
y1++;
} else {
x1++;
}
}
}
LCD_SetColor(Color0);
if (Vertical) {
if (y1 != y0) {
GUI_FillRect(x0, y0, x1, y1);
} else {
pfDrawLine(x0, y1, x1);
}
} else {
if (x1 != x0) {
GUI_FillRect(x0, y0, x1, y1);
} else {
pfDrawLine(x1, y0, y1);
}
}
LCD_SetColor(OldColor);
}
#endif
/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* GUI_DrawGradientV
*/
void GUI_DrawGradientV(int x0, int y0, int x1, int y1, GUI_COLOR Color0, GUI_COLOR Color1)
{
#if (GUI_WINSUPPORT)
GUI_RECT r;
#endif
GUI_LOCK();
#if (GUI_WINSUPPORT)
WM_ADDORG(x0,y0);
WM_ADDORG(x1,y1);
r.x0 = x0; r.x1 = x1;
r.y0 = y0; r.y1 = y1;
WM_ITERATE_START(&r); {
#endif
_DrawGradient(x0, y0, x1, y1, Color0, Color1, LCD_DrawHLine, 1);
#if (GUI_WINSUPPORT)
} WM_ITERATE_END();
#endif
GUI_UNLOCK();
}
/*********************************************************************
*
* GUI_DrawGradientH
*/
void GUI_DrawGradientH(int x0, int y0, int x1, int y1, GUI_COLOR Color0, GUI_COLOR Color1)
{
#if (GUI_WINSUPPORT)
GUI_RECT r;
#endif
GUI_LOCK();
#if (GUI_WINSUPPORT)
WM_ADDORG(x0,y0);
WM_ADDORG(x1,y1);
r.x0 = x0; r.x1 = x1;
r.y0 = y0; r.y1 = y1;
WM_ITERATE_START(&r); {
#endif
_DrawGradient(x0, y0, x1, y1, Color0, Color1, LCD_DrawVLine, 0);
#if (GUI_WINSUPPORT)
} WM_ITERATE_END();
#endif
GUI_UNLOCK();
} 你用16位的,你算法没改成相应的16位吗?如这里: r0 = (Color0>>0) & 0xff;
g0 = (Color0>>8) & 0xff;
b0 = (Color0>> 16) & 0xff;
faduo2012 发表于 2013-3-10 00:34 static/image/common/back.gif
你用16位的,你算法没改成相应的16位吗?如这里: r0 = (Color0>>0) & 0xff;
g0 = (Color0>>8) & 0xf ...
这个函数接口是在UCGUI系统环境下实现的,用户使用的颜色都是888真彩色,
当调用LCD_SetColor时会把相应的888转变成对应硬件支持的颜色。 自己顶起来,求推荐24BIT BMP转16BIT BMP小失真的软件!!
目前使用Photoshop Fireworks等转换均无果!! Floyd-Steinberg算法可以比较接近原图的转换,但是我也在找这块资料。
页:
[1]