虽然主题是C++和图形,但好象没有写过一篇关于图形的,现在发一个,添补空白。下面是一个同事写的实现8级ALPHA混合的算法,虽然只有8级,但比我用定点数写的实现任意级的要快许多倍。从这个示例可以看出算法的威力,也可以看出数学是多么重要。
/// 获取RGB分量的掩码
#define RGB565_R_MASK 0xF800
#define RGB565_G_MASK 0x07E0
#define RGB565_B_MASK 0x
#define RGB565_R_LBIT 0x0800
#define RGB565_G_LBIT 0x0020
#define RGB565_B_LBIT 0x0001
#define RGB565_R_MBIT 0x8000
#define RGB565_G_MBIT 0x0400
#define RGB565_B_MBIT 0x0010
/// 混合了RGB?位
#define RGB565_MSBIT (RGB565_R_MBIT | RGB565_G_MBIT | RGB565_B_MBIT)
#define RGB565_LSBIT (RGB565_R_LBIT | RGB565_G_LBIT | RGB565_B_LBIT)
#define RGB565_R_M2BIT (RGB565_R_MBIT | (RGB565_R_MBIT >> 1))
#define RGB565_G_M2BIT (RGB565_G_MBIT | (RGB565_G_MBIT >> 1))
#define RGB565_B_M2BIT (RGB565_B_MBIT | (RGB565_B_MBIT >> 1))
#define RGB565_R_M3BIT (RGB565_R_MBIT | (RGB565_R_MBIT >> 1) | (RGB565_R_MBIT >> 2))
#define RGB565_G_M3BIT (RGB565_G_MBIT | (RGB565_G_MBIT >> 1) | (RGB565_G_MBIT >> 2))
#define RGB565_B_M3BIT (RGB565_B_MBIT | (RGB565_B_MBIT >> 1) | (RGB565_B_MBIT >> 2))
void vBlendImage(unsigned int vAddr, 图像结构指针 lpImage, unsigned int xSrc, unsigned int ySrc, unsigned int width, unsigned int height, unsigned int coef)
{
unsigned int i,j,dwidth,dheight,deltawidth;
unsigned int* dp = (unsigned int *)vAddr, *dp1, *sp = lpImage->databuf;
if(xSrc >= (DTMAXX + 1) || ySrc >= (DTMAXY + 1)){
return;
}
dwidth = lpImage->width;
dheight = lpImage->height;
deltawidth = dwidth - width;
/* if(xSrc + width > (DTMAXX + 1)){
width = (DTMAXX + 1) - xSrc;
}
if(ySrc + height > (DTMAXY + 1)){
height = (DTMAXY + 1) - ySrc;
}*/
dp += (ySrc * (DTMAXX + 1) + xSrc);
for(i=0; i<height; i++){
dp1 = dp;
for(j=0; j<width; j++){
unsigned int scolor, dcolor;
unsigned int mcolor;
unsigned int skcolor, dkcolor;
unsigned int xcolor;
scolor = *sp++;
xcolor = dcolor = *dp1;
skcolor = scolor & RGB565_LSBIT;
scolor = scolor & ~RGB565_LSBIT;
dkcolor = dcolor & RGB565_LSBIT;
dcolor = dcolor & ~RGB565_LSBIT;
if(coef & BIT0){
mcolor = xcolor & skcolor;
xcolor = (xcolor & ~RGB565_LSBIT) + scolor;
xcolor = (xcolor >> 1) + mcolor;
}
if(coef & BIT1){
mcolor = xcolor & skcolor;
xcolor = (xcolor & ~RGB565_LSBIT) + scolor;
xcolor = (xcolor >> 1) + mcolor;
}else{
if(xcolor != dcolor){
mcolor = xcolor & dkcolor;
xcolor = (xcolor & ~RGB565_LSBIT) + dcolor;
xcolor = (xcolor >> 1) + mcolor;
}
}
if(coef & BIT2){
mcolor = xcolor & skcolor;
xcolor = (xcolor & ~RGB565_LSBIT) + scolor;
xcolor = (xcolor >> 1) + mcolor;
}else{
if(xcolor != dcolor){
mcolor = xcolor & dkcolor;
xcolor = (xcolor & ~RGB565_LSBIT) + dcolor;
xcolor = (xcolor >> 1) + mcolor;
}
}
*dp1++ = xcolor;
}
sp += deltawidth;
dp += (DTMAXX + 1);
}
}