这个问题研究几天了,一直没解决,急啊,大家帮我看看吧。我用CImage的Load函数直接加载32位带通道的BMP图,然后用AlphaBlend绘制,可以显示半透明位图。
不过我发现一个问题,例如用2进制打开位图,凡是为FFFFFF00 这样的点,AlphaBlend绘制都会显示为不透明的白色,可这里最后一个字节ALPHA通道设的是00,应该为全透明的……如果把这个点改为00000000,则全透明了。似乎CImage算透明度,不是用的最后一个字节(ALPHA通道)……而且,当ALPHA通道是00的时候,只要RGB中有一点色值,就还会画出来。实在是弄不懂这个CImage到底是怎么取和绘制ALPHA通道值的,希望知道内幕的大侠前来解惑……
不过我发现一个问题,例如用2进制打开位图,凡是为FFFFFF00 这样的点,AlphaBlend绘制都会显示为不透明的白色,可这里最后一个字节ALPHA通道设的是00,应该为全透明的……如果把这个点改为00000000,则全透明了。似乎CImage算透明度,不是用的最后一个字节(ALPHA通道)……而且,当ALPHA通道是00的时候,只要RGB中有一点色值,就还会画出来。实在是弄不懂这个CImage到底是怎么取和绘制ALPHA通道值的,希望知道内幕的大侠前来解惑……
In order to help you out, I have written the following test case
that demonstrates your problem and gives you the solution:
1) The test images came from here:
http://www.schaik.com/pngsuite/pngsuite.html
2) The window color on my desktop was blue ( COLOR_BACKGROUND )
HINSTANCE g_hinst;
CImage img;
Gdiplus::Image *img2;
class Window
{
public:
HWND GetHWND() { return m_hwnd; }
protected:
virtual LRESULT HandleMessage(
UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual void PaintContent(PAINTSTRUCT *pps)
{
img.AlphaBlend(pps->hdc, 0, 0 );
Gdiplus::Graphics graphics(pps->hdc);
graphics.SetInterpolationMode(Gdiplus::InterpolationModeHighQuality);
graphics.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality);
graphics.SetCompositingMode(Gdiplus::CompositingModeSourceOver);
graphics.DrawImage(img2, 0, 100, img2->GetWidth(), img2->GetHeight());
}
virtual LPCTSTR ClassName() = 0;
virtual BOOL WinRegisterClass(WNDCLASS *pwc)
{ return RegisterClass(pwc); }
virtual ~Window() { }
HWND WinCreateWindow(DWORD dwExStyle, LPCTSTR pszName,
DWORD dwStyle, int x, int y, int cx, int cy,
HWND hwndParent, HMENU hmenu)
{
Register();
return CreateWindowEx(dwExStyle, ClassName(), pszName, dwStyle,
x, y, cx, cy, hwndParent, hmenu, g_hinst, this);
}
private:
void Register();
void OnPaint();
void OnPrintClient(HDC hdc);
static LRESULT CALLBACK s_WndProc(HWND hwnd,
UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
HWND m_hwnd;
};
void Window::Register()
{
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = Window::s_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hinst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetSysColorBrush(COLOR_BACKGROUND);
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName();
WinRegisterClass(&wc);
}
LRESULT CALLBACK Window::s_WndProc(
HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Window *self;
if (uMsg == WM_NCCREATE) {
LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
self = reinterpret_cast<Window *>(lpcs->lpCreateParams);
self->m_hwnd = hwnd;
SetWindowLongPtr(hwnd, GWLP_USERDATA,
reinterpret_cast<LPARAM>(self));
} else {
self = reinterpret_cast<Window *>
(GetWindowLongPtr(hwnd, GWLP_USERDATA));
}
if (self) {
return self->HandleMessage(uMsg, wParam, lParam);
} else {
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
LRESULT Window::HandleMessage(
UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT lres;
switch (uMsg) {
case WM_NCDESTROY:
lres = DefWindowProc(m_hwnd, uMsg, wParam, lParam);
SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
delete this;
return lres;
case WM_PAINT:
OnPaint();
return 0;
case WM_PRINTCLIENT:
OnPrintClient(reinterpret_cast<HDC>(wParam));
return 0;
}
return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}
void Window::OnPaint()
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, &ps);
PaintContent(&ps);
EndPaint(m_hwnd, &ps);
}
void Window::OnPrintClient(HDC hdc)
{
PAINTSTRUCT ps;
ps.hdc = hdc;
GetClientRect(m_hwnd, &ps.rcPaint);
PaintContent(&ps);
}
class RootWindow : public Window
{
public:
virtual LPCTSTR ClassName() { return TEXT("AlphaBlend"); }
static RootWindow *Create();
protected:
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnCreate();
private:
HWND m_hwndChild;
};
LRESULT RootWindow::OnCreate()
{
img.Load(TEXT("C:\\Temp\\PngSuite\\TP1N3P08.PNG"));
img2 = Gdiplus::Image::FromFile(TEXT("C:\\Temp\\PngSuite\\TBWN3P08.PNG"),
FALSE);
return 0;
}
LRESULT RootWindow::HandleMessage(
UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_CREATE:
return OnCreate();
case WM_DESTROY:
if ( img2 )
delete img2;
return 0;
case WM_NCDESTROY:
// Death of the root window ends the thread
PostQuitMessage(0);
break;
case WM_SIZE:
if (m_hwndChild) {
SetWindowPos(m_hwndChild, NULL, 0, 0,
GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
SWP_NOZORDER | SWP_NOACTIVATE);
}
return 0;
case WM_SETFOCUS:
if (m_hwndChild) {
SetFocus(m_hwndChild);
}
return 0;
}
return __super::HandleMessage(uMsg, wParam, lParam);
}
RootWindow *RootWindow::Create()
{
RootWindow *self = new RootWindow();
if (self && self->WinCreateWindow(0,
TEXT("AlphaBlend"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL)) {
return self;
}
delete self;
return NULL;
}
int PASCAL
WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int nShowCmd)
{
g_hinst = hinst;
if (SUCCEEDED(CoInitialize(NULL))) {
InitCommonControls();
RootWindow *prw = RootWindow::Create();
if (prw) {
ShowWindow(prw->GetHWND(), nShowCmd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CoUninitialize();
}
return 0;
}
"Michael Phillips, Jr." <[email protected]> wrote in message
news:%23vc7%[email protected]...