因此,我遇到了将两个图像混合在一起以解决透明度问题。我在这里使用freetype来生成字形。我有一个相当大的代码库,所以我挑选了混合过程中涉及的大部分代码。
这是我正在使用的代码:
void TopDown(FT_Bitmap *bitmap, ... )
{
.....
.....
for (int srcY=0; srcY < bitmap->rows; srcY++, destLine += textureWidth, srcLine += bitmap->pitch)
{
unsigned char *currSrc = srcLine;
unsigned int *currDest = destLine;
for (int srcX=0; srcX < bitmap->width; srcX++, currSrc++)
{
unsigned char alpha = *currSrc * textA / 255;
if (currDest >= dest && currDest < destMax)
{
unsigned int destR = (textR * alpha + bgR * (255-alpha))/255;
unsigned int destG = (textG * alpha + bgG * (255-alpha))/255;
unsigned int destB = (textB * alpha + bgB * (255-alpha))/255;
unsigned int as = alpha;
*currDest = makeColor(destR, destG, destB, alpha);
}
currDest++;
}
}
}
答案 0 :(得分:0)
让此行unsigned char alpha = *currSrc * textA / 255
分成两行:
unsigned char alpha = *currSrc;
alpha = alpha * textA / 255;
这实际上是红色部分。您必须跳过3个字节才能获得alpha值:
unsigned char alpha = *currSrc + 3;
alpha = alpha * textA / 255;
您实际上并不需要。只需找到所有黑色像素并将其alpha值设置为零即可。确保文本颜色不是黑色。您可以使用0x00000001
来设置文本颜色,这会将其与黑色背景区分开。
void TopDown(...)
{
...
for(...)
{
...
for(...)
{
...
unsigned char r = *currSrc + 0;
unsigned char g = *currSrc + 1;
unsigned char b = *currSrc + 2;
unsigned char alpha = 128; //or 255 or whatever
if(currDest >= dest && currDest < destMax)
{
if(r || g || b)
{
//non-black pixels get alpha value
*currDest = makeColor(r, g, b, alpha);
}
else
{
//black pixels get zero alpha
*currDest = 0;
}
}
currDest++;
}
}
}
现在,您只需要绘制背景位图即可。如果使用正确的绘画功能,则无需混合。背景将显示为透明。手动混合颜色:
unsigned char blend2(unsigned char m, unsigned char n, unsigned char alpha)
{
float i = (float)n;
float j = (float)m;
float a = (float)alpha;
j *= a / 255.0f; //you can skip this step
int color = (int)((i + j)/2);
return (unsigned char)color;
}
void blendBitmap(...)
{
...
for (int line=0; line < copyHeight; line++)
{
T *destPtr = destBitmap->line(line+destRow) + 4*destCol;
unsigned char *sourcePtr = sourceBitmap->line(line+srcRow) + 4*srcCol;
if(destPtr && sourcePtr)
{
for (int col=0; col < copyWidth; col++, destPtr += 4, sourcePtr += 4)
{
unsigned char alpha = sourcePtr[3];
destPtr[0] = blend2(destPtr[0], sourcePtr[0], alpha);
destPtr[1] = blend2(destPtr[1], sourcePtr[1], alpha);
destPtr[2] = blend2(destPtr[2], sourcePtr[2], alpha);
}
}
}
}