Win32 LayeredWindow дает плохой визуальный эффект

Я разрабатываю систему пользовательского интерфейса, которая имеет все эти умные функции, такие как отрыв и стыковка панели и т. Д. Сейчас моя задача - создать наложение на экране, которое показывает положение, в котором приземлится оторванная или закрепляемая панель. Практически то же самое, что есть у визуальной студии. Для этого я использую настраиваемый класс многоуровневого окна, который будет отображаться, когда это необходимо. После этого я начал копать, чтобы добиться нужного эффекта. Раньше я работал со стандартными функциями GDI, и в основном они в порядке. Но на этот раз я последовал совету документации, чтобы использовать UpdateLayeredWindow для своих задач и загружать 32-битное изображение из растрового изображения вместо того, чтобы рисовать его с помощью функций GDI. Итак, у меня есть bmp шириной 128x128 пикселей с 222 в альфа-канале и 255 0 0 в RGB.

Вот методы, которые я использую для инициализации и рисования.

void Init(HDC in_hdc,HWND in_hwnd)
    {
        bf = { 0, 0, 200, AC_SRC_ALPHA };
        hwnd = in_hwnd;
        hdc_mem = CreateCompatibleDC(in_hdc);
        hBitmap_mem = CreateCompatibleBitmap(in_hdc, canvas_size.cx, canvas_size.cy);
        hBitmap_mem_default = (HBITMAP)SelectObject(hdc_mem, hBitmap_mem);
        hdc_bitmap = CreateCompatibleDC(in_hdc);
    }
    void DrawArea(RECT& in_rect)
    {
        hBitmap_area_default = (HBITMAP)SelectObject(hdc_bitmap, hBitmap_area);
        AlphaBlend(hdc_mem, in_rect.left, in_rect.top, in_rect.right, in_rect.bottom, hdc_bitmap, 0, 0, 2, 2, bf);
        hBitmap_area = (HBITMAP)SelectObject(hdc_bitmap, hBitmap_area_default);
    }
    void Update()
    {
        POINT p = { 0, 0 };
        HDC hdc_screen = GetDC(0);
        UpdateLayeredWindow(hwnd, hdc_screen, &p, &canvas_size, hdc_mem, &p, 0, &bf, ULW_ALPHA);
    }

В стиле окна есть эти дополнения WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST

И вот что я получаю. Итак, как вы можете видеть, происходящее смешивание ДЕЙСТВИТЕЛЬНО учитывает попиксельную альфу, но плохо справляется с работой по смешиванию. Есть идеи, как его настроить? введите описание изображения здесь


person Antiusninja    schedule 16.04.2015    source источник
comment
Почему вы используете 200 в своей структуре функции наложения. Для попиксельных альфа-значений необходимо использовать 255.   -  person γηράσκω δ' αεί πο    schedule 16.04.2015


Ответы (1)


Я подозреваю, что проблема в исходном растровом изображении. Это тот эффект, который вы получаете, когда значения RGB не умножаются на альфа-канал. Но игнорируйте это, потому что есть гораздо более простой способ сделать это.

  • Создайте многоуровневое окно со сплошным цветом фона, установив hbrBackground в структуре WNDCLASSEX.

  • Сделайте окно частично прозрачным, вызвав SetLayeredWindowAttributes.

  • Расположите окно там, где хотите.

Вот и все.

В этом ответе есть код, который иллюстрирует метод для несколько иной цели.

person arx    schedule 16.04.2015
comment
Спасибо за подсказку. А что, если мне понадобятся пиктограммы и значки, нарисованные с некоторыми эффектами прозрачности. (NavigationDiamond, как в редакторе VS - person Antiusninja; 16.04.2015
comment
Затем нужно исправить растровое изображение. Я не знаю, как вы это создаете, поэтому не могу добавить много. - person arx; 16.04.2015
comment
Спасибо. На самом деле предварительное умножение сработало. Тем не менее, я не могу понять идею этого предварительного умножения. Итак, если, например, у меня чистый красный цвет, который составляет 255 0 0 и 222 альфа, тогда, умножив 255 на 222 (0,87), я получу ~ 222 0 0 и альфа на 222, поэтому, когда после этого я умножу его на 1 / 0,87, я получу вернуть желаемый цвет. Но если я не умножу предварительно, 255 на 1 / .087 выходит за пределы одного байтового диапазона, и происходят разные неправильные вещи. Почему бы в первую очередь не взять оригинальные значения RGB? - person Antiusninja; 16.04.2015
comment
Причина проста: альфа-смешение с композицией Портера-Даффа (и, возможно, без; IDK) включает в себя множество умножений, которые с аппаратной точки зрения являются медленными. Заранее умножив красный, зеленый и синий компоненты на альфа-компонент, вы можете уменьшить количество умножений, выполняемых вашим кодом наложения, что сделает работу быстрее и эффективнее. - person andlabs; 16.04.2015