C++ 由于alpha值,将一个图像混合到另一个图像上会产生错误的图像
因此,我有一个问题,混合两个图像一起处理透明度。我在这里使用freetype来生成glyph。我有一个相当大的代码库,所以我选择了混合过程中涉及的主要代码部分 这是我正在使用的代码:C++ 由于alpha值,将一个图像混合到另一个图像上会产生错误的图像,c++,image-processing,C++,Image Processing,因此,我有一个问题,混合两个图像一起处理透明度。我在这里使用freetype来生成glyph。我有一个相当大的代码库,所以我选择了混合过程中涉及的主要代码部分 这是我正在使用的代码: void TopDown(FT_Bitmap *bitmap, ... ) { ..... ..... for (int srcY=0; srcY < bitmap->rows; srcY++, destLine += textureWidth, src
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++;
}
}
}
void top-down(FT_位图*位图,…)
{
.....
.....
对于(int srcY=0;srcYrows;srcY++,destLine+=textureWidth,srcLine+=bitmap->pitch)
{
无符号字符*currSrc=srcLine;
无符号int*currDest=destLine;
对于(int-srcX=0;srcXwidth;srcX++,currSrc++)
{
无符号字符alpha=*currSrc*textA/255;
如果(currDest>=dest&&currDest
让我们将这一行无符号字符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++;
}
}
}
void自上而下(…)
{
...
对于(…)
{
...
对于(…)
{
...
无符号字符r=*currSrc+0;
无符号字符g=*currSrc+1;
无符号字符b=*currSrc+2;
无符号字符alpha=128;//或255或其他
如果(currDest>=dest&&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);
}
}
}
}
unsigned char blend2(unsigned char m,unsigned char n,unsigned char alpha)
{
浮点数i=(浮点数)n;
浮动j=(浮动)m;
浮点a=(浮点)α;
j*=a/255.0f;//您可以跳过此步骤
int颜色=(int)((i+j)/2);
返回(无符号字符)颜色;
}
void blendBitmap(…)
{
...
用于(int line=0;lineline(line+destRow)+4*destCol;
无符号字符*sourcePtr=sourceBitmap->line(line+srcRow)+4*srcCol;
if(destPtr&&sourcePtr)
{
for(int col=0;col
“但是角色周围的块是完全透明的(您可以透过它们看到),为什么会发生这种情况?”因为纹理的alpha通道在该部分为0.0?尝试类似于textA=255-textA
或textA=(texA==0)的方法?255:textA
用于调试原因。@Rabbid76。我在unsigned int textA=(textColor&0xff000000)>>24之后添加了textA=255-textA
这就是你的意思吗?@rabbi76这样做,文本的透明度会丢失,看起来像这样@Scheff,以防万一你可以打开这个链接,图像看起来像这样。在这种情况下,文本的透明度会丢失,这是不正确的。除此之外,块的背景仍然是透明的。没有任何改变,只是文本的不透明度丢失。您确定“Hello”图像是正确的吗?看起来角色外部没有透明度。在这种情况下,混合实际上是正常的。