CImage 如何正确显示带ALPHA通道的 32BPP BMP位图?

diabear 2006-03-22 12:51:08
这个问题研究几天了,一直没解决,急啊,大家帮我看看吧。

我用CImage的Load函数直接加载32位带通道的BMP图,然后用AlphaBlend绘制,可以显示半透明位图。
不过我发现一个问题,例如用2进制打开位图,凡是为FFFFFF00 这样的点,AlphaBlend绘制都会显示为不透明的白色,可这里最后一个字节ALPHA通道设的是00,应该为全透明的……如果把这个点改为00000000,则全透明了。似乎CImage算透明度,不是用的最后一个字节(ALPHA通道)……而且,当ALPHA通道是00的时候,只要RGB中有一点色值,就还会画出来。实在是弄不懂这个CImage到底是怎么取和绘制ALPHA通道值的,希望知道内幕的大侠前来解惑……
...全文
773 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
diabear 2006-03-25
  • 打赏
  • 举报
回复
上面的回复似乎没能解释我的问题,我的问题简单说就是CImage的AlphaBlend的透明度似乎不是由32位位图每个像素的第四个字节决定的,正常的透明显示应该是通过设这个字节0~255来决定透明度,用CImage怎样才能正确的显示32位位图?
蒋晟 2006-03-22
  • 打赏
  • 举报
回复
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." <mphillips53@nospam.jun0.c0m> wrote in message

news:%23vc7%23RuiFHA.2152@TK2MSFTNGP14.phx.gbl...


19,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧