最近项目开发用到microwindows,却发现图片的显示不能透明。一般来说图象透明有二种方法,一种是ALPHA混合,另外一种就是把要求透明的象素不显示出来,即通过不画背景色来达到透明的效果。查看micorwindows的源代码,发现数据结构PMWIMAGEHDR中有一项transcolor是表示透明的,再继续查看这才发现transcolor设置的为-1,即默认是不显示透明的。修改源代码,在devimage.c中增加二个函数:
static PIMAGEITEM
findimage(int id)
{
PMWLIST p;
PIMAGEITEM pimagelist;
for (p=imagehead.head; p; p=p->next) {
pimagelist = GdItemAddr(p, IMAGEITEM, link);
if (pimagelist->id == id)
return pimagelist;
}
return NULL;
}
/**
* Set image transcolor.
*
* @param id Image to query.
* @param color image transcolor.
* @return TRUE on success, FALSE on error.
*/
MWBOOL
GdSetTransColor(int id, long color)
{
PIMAGEITEM pItem;
pItem = findimage(id);
if (!pItem) {
return FALSE;
}
pItem->pimage->transcolor = color;
return TRUE;
}
并把GdSetTransColor注册进device.h中
然后在srvfunc.c中增加一函数
/* set image transcolor*/
void
GrSetTransColor(GR_IMAGE_ID id, long color)
{
SERVER_LOCK();
GdSetTransColor(id, color);
SERVER_UNLOCK();
}
并注册进nano-X.h中。
现在源码修改完毕,应用程序只要调用GrSetTransColor函数就能实现透明处理。但是这里要注意的是,对于透明处理,如果创建窗口,如果load图片也是有规律的,有可能是能够显示图片但是就是不能透明,这可能就是没有按顺序load图片的原因。一般来说,顺序是这样的:
1、获得图片。
if(!(imageid = GrLoadImageFromFile(imagepath[iNum], 0))) {
PDEBUG("Failed to load image file/n");
GrClose();
return -1;
}
2、获得图片信息。
GrGetImageInfo(imageid, &iif);
3、根据图片信息创建窗口
wid = GrNewWindow(GR_ROOT_WINDOW_ID, position[iNum][0], position[iNum][1],
iif.width, iif.height, 0, 0, 0);
4、设置窗口属性
GR_WM_PROPERTIES props;
props.flags = GR_WM_FLAGS_PROPS;
props.props = GR_WM_PROPS_NOBACKGROUND;
GrSetWMProperties(window, &props);
5、下面要计算处color的值,也就是透明色的值,先在.h中定义几个宏
#define TRANSCOLOR_RGB565(r, g, b) ((((r)<<11)&0xF8) | (((g)<<5)&0x7E) | ((b)&0x1F))
#define TRANSCOLOR_RGB555(r, g, b) ((((r)<<10)&0x7C) | (((g)<<5)&0x3E) | ((b)&0x1F))
#define TRANSCOLOR_ALPHA 0xFF
#define TRANSCOLOR_R 211
#define TRANSCOLOR_G 230
#define TRANSCOLOR_B 234
这里(211,230,234)是你要透明的颜色,如果你不知道透明颜色的RGB,可以用PHOTOSHOP软件那吸管来查看,我这里用的就是用PHOTOSHOP查看的。
好了,现在处理透明
switch(iif.bpp)
{
case 15:
color = PIXEL565TOCOLORVAL(TRANSCOLOR_RGB555(TRANSCOLOR_R, TRANSCOLOR_G, TRANSCOLOR_B));
break;
case 16:
color = PIXEL565TOCOLORVAL(TRANSCOLOR_RGB565(TRANSCOLOR_R, TRANSCOLOR_G, TRANSCOLOR_B));
break;
case 24:
color = MWRGB(TRANSCOLOR_R, TRANSCOLOR_G, TRANSCOLOR_B);
break;
case 32:
color = MWARGB(TRANSCOLOR_ALPHA, TRANSCOLOR_R, TRANSCOLOR_G, TRANSCOLOR_B);
break;
default:
color = 0;
break;
}
6、调用GrSetTransColor函数,并填充窗口
GrSetTransColor(imageid, color);
GrDrawImageToFit(wid, gc, 0, 0, image[iNum].width, image[iNum].height, imageid);
如果你根据我的修改了源代码,并按照上面的顺序来调用的话,就可以透明了。
static PIMAGEITEM
findimage(int id)
{
PMWLIST p;
PIMAGEITEM pimagelist;
for (p=imagehead.head; p; p=p->next) {
pimagelist = GdItemAddr(p, IMAGEITEM, link);
if (pimagelist->id == id)
return pimagelist;
}
return NULL;
}
/**
* Set image transcolor.
*
* @param id Image to query.
* @param color image transcolor.
* @return TRUE on success, FALSE on error.
*/
MWBOOL
GdSetTransColor(int id, long color)
{
PIMAGEITEM pItem;
pItem = findimage(id);
if (!pItem) {
return FALSE;
}
pItem->pimage->transcolor = color;
return TRUE;
}
并把GdSetTransColor注册进device.h中
然后在srvfunc.c中增加一函数
/* set image transcolor*/
void
GrSetTransColor(GR_IMAGE_ID id, long color)
{
SERVER_LOCK();
GdSetTransColor(id, color);
SERVER_UNLOCK();
}
并注册进nano-X.h中。
现在源码修改完毕,应用程序只要调用GrSetTransColor函数就能实现透明处理。但是这里要注意的是,对于透明处理,如果创建窗口,如果load图片也是有规律的,有可能是能够显示图片但是就是不能透明,这可能就是没有按顺序load图片的原因。一般来说,顺序是这样的:
1、获得图片。
if(!(imageid = GrLoadImageFromFile(imagepath[iNum], 0))) {
PDEBUG("Failed to load image file/n");
GrClose();
return -1;
}
2、获得图片信息。
GrGetImageInfo(imageid, &iif);
3、根据图片信息创建窗口
wid = GrNewWindow(GR_ROOT_WINDOW_ID, position[iNum][0], position[iNum][1],
iif.width, iif.height, 0, 0, 0);
4、设置窗口属性
GR_WM_PROPERTIES props;
props.flags = GR_WM_FLAGS_PROPS;
props.props = GR_WM_PROPS_NOBACKGROUND;
GrSetWMProperties(window, &props);
5、下面要计算处color的值,也就是透明色的值,先在.h中定义几个宏
#define TRANSCOLOR_RGB565(r, g, b) ((((r)<<11)&0xF8) | (((g)<<5)&0x7E) | ((b)&0x1F))
#define TRANSCOLOR_RGB555(r, g, b) ((((r)<<10)&0x7C) | (((g)<<5)&0x3E) | ((b)&0x1F))
#define TRANSCOLOR_ALPHA 0xFF
#define TRANSCOLOR_R 211
#define TRANSCOLOR_G 230
#define TRANSCOLOR_B 234
这里(211,230,234)是你要透明的颜色,如果你不知道透明颜色的RGB,可以用PHOTOSHOP软件那吸管来查看,我这里用的就是用PHOTOSHOP查看的。
好了,现在处理透明
switch(iif.bpp)
{
case 15:
color = PIXEL565TOCOLORVAL(TRANSCOLOR_RGB555(TRANSCOLOR_R, TRANSCOLOR_G, TRANSCOLOR_B));
break;
case 16:
color = PIXEL565TOCOLORVAL(TRANSCOLOR_RGB565(TRANSCOLOR_R, TRANSCOLOR_G, TRANSCOLOR_B));
break;
case 24:
color = MWRGB(TRANSCOLOR_R, TRANSCOLOR_G, TRANSCOLOR_B);
break;
case 32:
color = MWARGB(TRANSCOLOR_ALPHA, TRANSCOLOR_R, TRANSCOLOR_G, TRANSCOLOR_B);
break;
default:
color = 0;
break;
}
6、调用GrSetTransColor函数,并填充窗口
GrSetTransColor(imageid, color);
GrDrawImageToFit(wid, gc, 0, 0, image[iNum].width, image[iNum].height, imageid);
如果你根据我的修改了源代码,并按照上面的顺序来调用的话,就可以透明了。