这个问题研究几天了,一直没解决,急啊,大家帮我看看吧。我用CImage的Load函数直接加载32位带通道的BMP图,然后用AlphaBlend绘制,可以显示半透明位图。
不过我发现一个问题,例如用2进制打开位图,凡是为FFFFFF00 这样的点,AlphaBlend绘制都会显示为不透明的白色,可这里最后一个字节ALPHA通道设的是00,应该为全透明的……如果把这个点改为00000000,则全透明了。似乎CImage算透明度,不是用的最后一个字节(ALPHA通道)……而且,当ALPHA通道是00的时候,只要RGB中有一点色值,就还会画出来。实在是弄不懂这个CImage到底是怎么取和绘制ALPHA通道值的,希望知道内幕的大侠前来解惑……

解决方案 »

  1.   

    7/17/2005 2:06:29 PM    Re: AlphaBlend CImage 
    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]... 
      

  2.   

    上面的回复似乎没能解释我的问题,我的问题简单说就是CImage的AlphaBlend的透明度似乎不是由32位位图每个像素的第四个字节决定的,正常的透明显示应该是通过设这个字节0~255来决定透明度,用CImage怎样才能正确的显示32位位图?