Отображение 32-битного изображения с альфа-каналом в Win32

Снимок экрана: http://i.imgur.com/hbExq9N.jpg

Здравствуйте, я пытаюсь установить png с альфа-каналом поверх статического элемента управления, но прозрачные пиксели всегда заполняют белый или черный цвет.

Не критично, если изображение находится поверх статического элемента управления или просто нарисовано в главном окне.

Если у вас есть идеи, поделитесь своим мнением.
THX

Извините, у меня должен быть почтовый индекс раньше

//First try loading icon with transparency to static control or button:
//static control;

HWND hL;
HICON iStick;
case WM_CREATE:
iStick = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 0, 0, LR_LOADTRANSPARENT);
hL = CreateWindow(L"STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP/*SS_ICON*/, 193, 290, 32, 32, hwnd, NULL, hInst, NULL);
SendMessage(hL, STM_SETIMAGE, IMAGE_ICON, (LPARAM)iStick);
//SendMessage(hL, STM_SETICON, IMAGE_ICON, (LPARAM)iStick);

//Second try to draw on background 32bit bmp A8R8G8B8 : 

PAINTSTRUCT ps;
HDC hdc;
RECT r;
static HDC membit;
static BITMAP bm;

case WM_CREATE:
    SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED);
    SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE |SWP_NOSIZE);
    SetLayeredWindowAttributes(hWnd, 0, (255 * 100) / 100, LWA_ALPHA);
    hStick = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP15));
    GetObject(hStick, sizeof(bm), &bm);
    membit = CreateCompatibleDC(hdc);
    SelectObject(membit, hStick);
    ReleaseDC(hWnd, hdc);

case WM_CTLCOLOREDIT:
    SetTextColor((HDC)wParam, RGB(65, 65, 65));      //
    return 0;

//MakeStaticbackground transparent
case WM_CTLCOLORSTATIC:       
    SetBkMode((HDC)wParam, TRANSPARENT);             //  
    SetTextColor((HDC)wParam, RGB(38, 205, 247));    //
    return (BOOL)GetStockObject(NULL_BRUSH);    

case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);

    GetClientRect(hWnd, &r);

    FillRect(hdc, &r, hBrush);
    SetBkMode(hdc, TRANSPARENT);

    BLENDFUNCTION BlendFunction;
    BlendFunction.AlphaFormat = AC_SRC_ALPHA;
    BlendFunction.BlendFlags = 0;
    BlendFunction.BlendOp = AC_SRC_OVER;
    BlendFunction.SourceConstantAlpha = 255;

    //BitBlt(hdc, 500, 280, bm.bmWidth, bm.bmHeight, membit, 0, 0, SRCCOPY);

    AlphaBlend(hdc, 500, 280, bm.bmWidth, bm.bmHeight, membit, 0, 0, 32, 32, BlendFunction);

    //TransparentBlt(hdc, 500, 300, 32, 32, membit, 32, 32, 32, 32, RGB(255, 255, 255));

    EndPaint(hWnd, &ps);

    break;

case WM_ERASEBKGND:
    return (LRESULT)1;

И еще, чего я не помню, но пиксели фона всегда заполняют белый или черный цвет.


person Borys Shobat    schedule 05.04.2015    source источник
comment
Пожалуйста, разместите свой код.   -  person andlabs    schedule 05.04.2015
comment
@Borys - Вы не показываете ни то, как загружаете изображение, ни как его рисуете. Ожидается, что вы, как задающий вопрос, сделаете вопрос настолько простым, насколько это возможно. Отредактируйте свой вопрос, чтобы показать свой подход, если вы хотите указать на недостатки в нем.   -  person enhzflep    schedule 06.04.2015
comment
Спасибо за ответ Я добавил код   -  person Borys Shobat    schedule 09.04.2015


Ответы (1)


Я думаю, вам нужна просто прозрачность, а не альфа-канал. Вам понадобится LWA_COLORKEY вместо LWA_ALPHA

SetLayeredWindowAttributes(hWnd, window_background_brush, 255, LWA_COLORKEY);

Это заменит window_background_brush прозрачным цветом. Если фоновая кисть не установлена, нужно установить, желательно белый цвет. Также лучше использовать значок, иначе у вас будут шероховатости. Вот пример кода для рисования значка:

HDC hDC = ::GetDC(m_hWnd);
HICON hicon = (HICON)LoadImage(NULL, "fullpath.ico", IMAGE_ICON, w, h, LR_LOADFROMFILE);
DrawIconEx(hDC, x, y, hicon, w, h, 0, NULL, DI_NORMAL);
DestroyIcon(hicon);
::ReleaseDC(m_hWnd, hDC);
person Barmak Shemirani    schedule 09.04.2015
comment
Спасибо, Barmak, ваш код работает хорошо, но я использовал ваш код в функции, которая опрашивает джойстик 60 раз в секунду. Я получил следующее: i.imgur.com/jha99iQ.gif?1 HDC hDC = :: GetDC (hwnd); DrawIconEx (hDC, 193 + (js.lX / 22), 290 + (js.lY / 22), iStick, 32, 32, 0, NULL, DI_NORMAL); DrawIconEx (hDC, 340 + (js.lZ / 22), 290 + (js.lRz / 22), iStick, 32, 32, 0, NULL, DI_NORMAL); // DestroyIcon (iStick); ReleaseDC (hwnd, hDC); - person Borys Shobat; 10.04.2015
comment
Отлично. Но есть много мерцания, или, может быть, это вызвано снимком экрана. Я думал, что вам нужна прозрачность для фонового изображения, но, похоже, это не так. Я бы удалил WS_EX_LAYERED и SetLayeredWindowAttributes. Нарисуйте фоновое изображение обычным растровым изображением. Рисуйте только движущиеся черные спрайты с иконкой. Также добавьте WS_CLIPCHILDREN. Если мерцание все еще присутствует, вы можете попробовать ExcludeClipRect, чтобы вручную исключить область управления в рисовании. - person Barmak Shemirani; 10.04.2015