Posted on 2008-09-19 16:17
沒畫完的畫 閱讀(2311)
評論(5) 編輯 收藏 引用 所屬分類:
VC
圖形學中,Alpha指的是除了顏色的三個分量(RGB)外的第四個分量,透明度
一個真彩色的像素由四個分量組成,RGBA
Alpha 的值在 0 到 1 之間,0表示完全透明,1 表示完全覆蓋
圖像A 和 圖像B 組合而成的圖像為 C
A: (R_Value_A, G_Value_A, B_Value_A, Alpha_A)
B: (R_Value_B, G_Value_B, B_Value_B, Alpha_B)
混合后的C 顏色為
R_Value_C = R_Value_A * Alpha_A + R_Value_B * Alpha_B
G_Value_C = G_Value_A * Alpha_A + G_Value_B * Alpha_B
B_Value_C = B_Value_A * Alpha_A + B_Value_B * Alpha_B
具體實現代碼:
/**
* alpha 值的范圍為 0 ~ 255
*/
inline COLORREF AlphaPixel(UINT alpha, COLORREF clr1, COLORREF clr2)


{
double k = (double)alpha / 256.0;
double reverse_k = 1.0 - k;
BYTE r = BYTE( GetRValue(clr2) * k + GetRValue(clr1) * reverse_k );
BYTE g = BYTE( GetGValue(clr2) * k + GetGValue(clr1) * reverse_k );
BYTE b = BYTE( GetBValue(clr2) * k + GetBValue(clr1) * reverse_k );
return RGB(r, g, b);
}

透明度 50%

for(int i = 0; i < size.cx; i++)

{
for ( int j = 0; j < size.cy; j++ )

{
pDC->SetPixel(i, j, AlphaPixel(255 / 2, RGB(255, 255, 255), dc.GetPixel(i, j)) );
}// for j
}// for i


如此算法,如果是1024 * 768 的圖,就很慢了,需要想辦法優化
餓了,先去吃飯再研究~
吃完飯,繼續
windows已經提供了 實現alpha混合的API
BOOL AlphaBlend(
HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
BLENDFUNCTION blendFunction);
前面十個參數不用說了,主要在最后一個參數
typedef struct _BLENDFUNCTION
{
BYTE BlendOp; // BlendOp字段指明了源混合操作,但只支持AC_SRC_OVER,即根據源alpha值把源圖像
疊加到目標圖像上
// OpenGL的alpha混合還支持其他的方式,如常量顏色源。
BYTE BlendFlags; // 保留字段,必須是 0
BYTE SourceConstantAlpha; //
BYTE AlphaFormat; // 0表示常量alpha值,AC_SRC_ALPHA表示每個像素有各自的alpha通道。
} BLENDFUNCTION;
BLENDFUNCTION結構控制源和目標位圖的混合方式
如果AlphaFormat字段為0,源位圖中的所有像素使用同樣的常量alpha值,即SourceConstantAlpha字段中的值,該值實際上是0和255
,而不是0和1。這里0表示完
全透明,255表示完全不透明。目標像素以255-SourceConstantAlpha值作為alpha值。
如果AlphaFormat字段的值是AC_SRC_ALPHA,源設備表面的每個像素必須有各自的alpha通道。即,必須是32-bpp的物理設備上下文
,或是選中了32-bpp DDB和DIB
段的內存設備上下文。這些情況下,每個源像素有4個8位通道:紅、綠、藍和alpha。每個像素的alpha通道和SourceConstantAlpha
字段一起用于把源和目標混合
起來。實際用于計算的運算式如下:
Tmp.Red = Src.Red * SourceConstantAlpha / 255;
Tmp.Green = Src.Green * SourceConstantAlpha / 255;
Tmp.Blue = Src.Blue * SourceConstantAlpha / 255;
Tmp.Alpha = Src.Alpha * SourceConstantAlpha / 255;
Beta = 255 – Tmp.alpha;
Dst.Red = Tmp.Red + Round((Beta * Dst.Red )/255);
Dst.Green = Tmp.Green + Round((Beta * Dst.Green)/255);
Dst.Blue = Tmp.Blue + Round((Beta * Dst.Blue )/255);
Dst.Alpha = Tmp.Alpha + Round((Beta * Dst.Alpha)/255);
如果AlphaFormat字段的值是AC_SRC_ALPHA 的情況還沒搞懂是什么意思