前段时间研究三角函数在图像处理的应用,要实现的是一个三角函数方式的渐进透明度,但是实现中出现的一个问题非常不解,就是设置像素alpha通道没有效果的问题。
首先贴上代码
void OnPaint(HWND hWnd)
{
RECT rc;
GetClientRect(hWnd, &rc);
int width = 180;
int height = 100;
int left = (rc.right - rc.left - width)/2;
int top = (rc.bottom - rc.top-height)/2;
HDC hDC = GetDC(hWnd);
SaveDC(hDC);
HBRUSH br = CreateSolidBrush(RGB(0,0,0));
SelectObject(hDC, br);
FillRect(hDC, &rc, br);
HDC memDC = CreateCompatibleDC(hDC);
int x = 180;
int y = 2;
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = x;
bmi.bmiHeader.biHeight = y;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = x*y*4;
bmi.bmiHeader.biClrUsed = 0;
LPBYTE pData = NULL;
HBITMAP dibmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pData, NULL, 0);
if(dibmp && pData)
{
for(int i = 0; i < x*y; ++i)
{
float alpha = FastSin(i%x);
pData[i*4] = 255 * alpha; //b
pData[i*4+1] = 255 * alpha; //g
pData[i*4+2] = 255 * alpha; //r
pData[i*4+3] = 255 * alpha; //alpha
}
}
HBITMAP oldBmp = (HBITMAP)SelectObject(memDC, dibmp);
BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
AlphaBlend(hDC, left, top, width, height, memDC, 0,0,x, y, bf);
SelectObject(memDC, oldBmp);
DeleteObject(dibmp);
RestoreDC(hDC, -1);
ReleaseDC(hWnd,hDC);
}
----------------------------------------------
一开始的代码不是这样的,而是下面这样
for(int i = 0; i < x*y; ++i)
{
float alpha = FastSin(i%x);
pData[i*4] = 255; //b
pData[i*4+1] = 255; //g
pData[i*4+2] = 255; //r
pData[i*4+3] = 255 * alpha; //alpha
}
这样无论alpha是多少,都没有效果,后来我把背景换成白色
代码改成
for(int i = 0; i < x*y; ++i)
{
float alpha = FastSin(i%x);
pData[i*4] = 0; //b
pData[i*4+1] = 0; //g
pData[i*4+2] = 0; //r
pData[i*4+3] = 255 * alpha; //alpha
}
发现有渐进效果,但是只要rgb设置了任何常数字都有问题,最后查找各种资料才明白原来dib位图在gdi绘制时alpha通道要进行RGB预乘的
最后就是上面代码的效果,正弦的透明渐进效果