我有几个带Alpha通道的32位位图。
我需要编写一个新的Bitmap,它再次有一个alpha通道。因此,最终的位图稍后将与AlphaBlend一起使用。
无需拉伸。如果没有alpha通道,我只会使用BitBlt来创建新的位图。
我没有使用托管代码,我只想用标准的GDI / WinAPI函数来做这件事。此外,我感兴趣的是一个不需要某些特殊库的解决方案。
TIA
注意:我知道我可以使用几个AphaBlend函数在最终输出中执行相同的组合。但是为了在我的程序中易于使用,我宁愿一次编写这样的位图。
答案 0 :(得分:0)
您可以浏览每个像素并手动撰写:
void ComposeBitmaps(BITMAP* bitmaps, int bitmapCount, BITMAP& outputBitmap)
{
for(int y=0; y<outputBitmap.bmHeight; ++y)
{
for(int x=0; x<outputBitmap.bmWidth; ++x)
{
int b = 0;
int g = 0;
int r = 0;
int a = 0;
for(int i=0; i<bitmapCount; ++i)
{
unsigned char* samplePtr = (unsigned char*)bitmaps[i].bmBits+(y*outputBitmap.bmWidth+x)*4;
b += samplePtr[0]*samplePtr[3];
g += samplePtr[1]*samplePtr[3];
r += samplePtr[2]*samplePtr[3];
a += samplePtr[3];
}
unsigned char* outputSamplePtr = (unsigned char*)outputBitmap.bmBits+(y*outputBitmap.bmWidth+x)*4;
if(a>0)
{
outputSamplePtr[0] = b/a;
outputSamplePtr[1] = g/a;
outputSamplePtr[2] = r/a;
outputSamplePtr[3] = a/bitmapCount;
}
else
outputSamplePtr[3] = 0;
}
}
(假设所有位图都是32位且具有相同的宽度和高度)
或者,如果你想在另一个上面绘制位图,而不是以相同的比例混合它们:
unsigned char* outputSamplePtr = (unsigned char*)outputBitmap.bmBits+(y*outputBitmap.bmWidth+x)*4;
outputSamplePtr[3] = 0;
for(int i=0; i<bitmapCount; ++i)
{
unsigned char* samplePtr = (unsigned char*)bitmaps[i].bmBits+(y*outputBitmap.bmWidth+x)*4;
outputSamplePtr[0] = (outputSamplePtr[0]*outputSamplePtr[3]*(255-samplePtr[3])+samplePtr[0]*samplePtr[3]*255)/(255*255);
outputSamplePtr[1] = (outputSamplePtr[1]*outputSamplePtr[3]*(255-samplePtr[3])+samplePtr[1]*samplePtr[3]*255)/(255*255);
outputSamplePtr[2] = (outputSamplePtr[2]*outputSamplePtr[3]*(255-samplePtr[3])+samplePtr[2]*samplePtr[3]*255)/(255*255);
outputSamplePtr[3] = samplePtr[3]+outputSamplePtr[3]*(255-samplePtr[3])/255;
}
答案 1 :(得分:0)
我找到了最适合我的解决方案。
由于位图不重叠,我不需要关注目标数据。