Как на лету создать растровое изображение с альфа-каналом с помощью GDI?

Я использую многоуровневые окна и рисую на экране прямоугольник с закругленными углами. Однако хотелось бы сгладить неровные края. Думаю, для этого мне понадобится альфа-смешивание. Есть ли способ сделать это с помощью GDI?


person wkf    schedule 24.07.2009    source источник


Ответы (4)


CreateDIBSection. Заполните BITMAPINFOHEADER 32bpp. Заполните альфа-канал предварительно умноженным альфа-каналом, и все готово.

AlphaBlend - это API для преобразования растровых изображений 32 бит на пиксель с каналом aplha.

person Chris Becke    schedule 25.07.2009

Вы можете сделать это на C #, используя метод LockBits класса BitMap (см. этот вопрос для объяснения). Вы определенно не хотите использовать для этого GetPixel и SetPixel, поскольку они ужасно медленные (даже если вы будете манипулировать только краями, а не всем растровым изображением).

person MusiGenesis    schedule 24.07.2009
comment
К сожалению, я не использую управляемый язык. Мне нужно использовать стандартные Windows API. - person wkf; 24.07.2009
comment
Это выполнимо, но не для меня. знак равно - person MusiGenesis; 24.07.2009

Есть ли шанс использовать GDI + вместо GDI? Он поддерживает сглаживание и прозрачность прямо из коробки.

person Mark Ransom    schedule 24.07.2009
comment
Если бы я действительно использовал GDI +, я бы застрял на плоских API, которые кажутся менее удобными в использовании. Хотя, если бы GDI + облегчил мою работу, я бы захотел переключиться на что-то более «классное». Я проверю это; Благодарность! - person wkf; 25.07.2009
comment
У меня также есть проблема с неровными линиями, и я использую GDI +, когда делаю CImage::AlphaBlend - person sergiol; 09.11.2016
comment
@sergiol в этом заявлении недостаточно информации, чтобы помочь вам. Предлагаю открыть новый вопрос. - person Mark Ransom; 09.11.2016

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

То, что я делал в прошлом для решения подобных проблем, - это использовать художественную программу, чтобы нарисовать любую форму, которую я хочу (например, закругленный угол), намного больше, чем мне нужно, в черно-белом режиме. Когда я хотел его нарисовать, я масштабировал черно-белое растровое изображение до любого размера, который хотел (используя вариант класс масштабирования из Code Project). Это дает мне изображение в градациях серого, которое я могу использовать в качестве альфа-канала, который затем использовал бы для альфа-смешивания, либо путем вызова функции AlphaBlend Win32, либо с помощью DIBSection и ручного изменения соответствующих пикселей.

Другой вариант этого подхода - выделить DIBSection примерно в четыре раза больше, чем вы хотели получить конечный результат, нарисовать его, а затем использовать указанный выше класс масштабирования для его уменьшения: масштабирование от большего изображения даст соответствующий эффект сглаживания .

Если все это звучит как довольно большая работа: что ж, это так.

РЕДАКТИРОВАТЬ: Чтобы ответить на заголовок этого вопроса: вы можете создать растровое изображение с альфа-каналом, вызвав CreateDIBSection. Я думаю, это само по себе не сделает того, что вы хотите.

person DavidK    schedule 24.07.2009
comment
Сегодня днем ​​я наткнулся на CreateDIBSection, просматривая MSDN, и, похоже, это часть, которую мне не хватало. Я использую алгоритмы линии / круга Ву для рисования линий и кругов со сглаживанием; пока у меня есть доступ к фактическим данным пикселей, я могу установить для них все, что захочу. И ты прав; оказывается, что работы много! ;п - person wkf; 25.07.2009
comment
Похоже, вы в основном там. Разделы DIB отлично подходят для работы с графикой: вы получаете дескриптор HBITMAP, но вы также можете получить доступ к необработанным данным пикселей. - person DavidK; 25.07.2009
comment
Сглаживание не уменьшает масштаб, а добавляет дополнительные пиксели затенения по диагонали или изогнутые края, чтобы придать ему более плавный вид. Это работает НАМНОГО лучше, если ваши добавленные пиксели имеют альфа-компонент (т.е. они используют альфа-смешение). - person Eric; 25.07.2009