我有一个用WS_EX_LAYERED窗口样式创建的窗口。目前,我正在使用GDI+绘制内存位图,并使用UpdateLayeredWindow更新分层窗口的图形内容。
下面是我的代码片段:
void Redraw(HWND hWnd, int width, int height) {
static bool floppy = true;
floppy = !floppy;
HDC hScreenDC = GetDC(HWND_DESKTOP);
HDC hMemDC = CreateCompatibleDC(hScreenDC);
HBITMAP hBmp = CreateCompatibleBitmap(hScreenDC, width, height);
HGDIOBJ hObj = SelectObject(hMemDC, hBmp);
Graphics gfx(hMemDC);
SolidBrush b(Color(254, (floppy ? 255 : 0), (floppy ? 0 : 255), 0));
gfx.FillRectangle(&b, Rect(0, 0, width, height));
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
POINT src = { 0, 0 };
SIZE size;
size.cx = width;
size.cy = height;
Assert(UpdateLayeredWindow(
hWnd,
hScreenDC,
NULL,
&size,
hMemDC,
&src,
RGB(0, 0, 0),
&blend,
ULW_ALPHA
));
SelectObject(hMemDC, hObj);
DeleteObject(hBmp);
DeleteDC(hMemDC);
ReleaseDC(HWND_DESKTOP, hScreenDC);
}在创建我的SolidBrush时,我为alpha组件指定了254的值。这会导致99.6%的不透明填充,这不是我想要的。
当我指定255作为alpha组件时,似乎没有填充;我的窗口变得完全透明。这是一个问题,因为我希望画的形状100%不透明,但我也希望画一些不是。
发布于 2013-10-07 02:47:07
似乎有一些与FillRectangle有关的qwerk。当我们观察到使用FillEllipse与α分量为255的SolidBrush一起使用时,就会发现形状呈现得非常完美(不透明)。
以下是我提出的两项工作,每一项都为我解决了这个问题:
FillRectangle
SolidBrush b(颜色(254,255,0,0);gfx.FillRectangle(&b,Rect(0,0,宽度,高度));gfx.FillRectangle(&b,Rect(0,0,宽度,高度));
由于同一区域被填充了两次,它们将混合并创建RGB(255,0,0),而不管窗口后面的内容(现在是100%不透明的)。我不喜欢这种方法,因为它要求每个矩形绘制两次。FillPolygon 代替
就像FillEllipse一样,FillPolygon似乎没有颜色问题,,除非你这样称呼它,:
SolidBrush b(颜色( 255,255,0,0);点points4;点=点(0,0);points1 =点(宽度,0);points2 =点(宽度,高度);points4 =点(0,高度);gfx.FillPolygon(&b,点,4);//不要复制和粘贴-这是行不通的
以上代码将产生100%透明的窗口。我猜想,这要么是由于某种形式的优化,而是将调用传递给FillRectangle。或者--很可能-- FillPolygon存在一些问题,这是由FillRectangle调用的。但是,如果在数组中添加一个额外的Point,则可以绕过它:
SolidBrush b(颜色( 255,255,0,0);点points5;点=点(0,0);points1 =点(0,0);//<- points2 =点(宽度,0);points3 =点(宽度,高度);points4 =点(0,高度);gfx.FillPolygon(&b,点,5);
以上代码将确实绘制一个100%不透明的形状,这解决了我的问题。发布于 2013-10-06 23:14:48
UpdateLayeredWindow()需要一个位图,其中包含预乘的alpha:
请注意,API使用预乘alpha,这意味着位图中的红色、绿色和蓝色通道值必须与alpha通道值进行预乘。例如,如果alpha通道值为x,则红色、绿色和蓝色通道必须乘以x,并在调用之前除以0xff。
您可以使用Bitmap::ConvertFormat()将位图转换为预乘(格式为PixelFormat32bppPARGB)。
https://stackoverflow.com/questions/19214921
复制相似问题