Чтение онлайн

ЖАНРЫ

Программирование на Visual C++. Архив рассылки

Jenter Алекс

Шрифт:

 

imgList.Draw(pDC, 0, m_drawPoint, ILD_TRANSPARENT);

Здесь pDC – указатель на контекст устройства (CDC), 0 – порядковый номер выводимого из списка изображения, m_drawPoint — координаты начала области вывода. Флаг ILD_TRANSPARENT указывает, что вывод нужно осуществлять с учетом маски прозрачности.

Для самых любознательных сообщу, что реализация эффекта прозрачности при этом достигается методом, который Рон Джери называет Black Source Method, т.е., "метод черного источника". Он позволяет выводить изображение с прозрачными участками за два вызова BitBlt вместо трех, но требует предварительно заменить пикселы, являющиеся прозрачными, черным цветом. Поэтому,

загружая растр в список изображений, вы меняете его.

В результате вызова получится примерно вот что.

Отметим, что такой метод работает по принципу "все или ничего": если цвет пиксела изображения отличается от прозрачного хоть на один бит, он считается непрозрачным, что и заметно на примере области тени. Разница может быть незаметной для человеческого глаза, но не для компьютера. Зачастую спрайты рисуют в графических редакторах, сглаживающих картинку. При выводе такого изображения образуется ореол из пикселов, близких по цвету к прозрачному цвету фона, но все же не прозрачных (эффект гало). Поэтому рекомендуется рисовать такие растры на фоне, близком по цвету к фону выводимого изображения.

Windows 98 и библиотека msimg32.dll

Windows 98 принесла новый простой способ вывода прозрачных изображений. Входящая в ее состав библиотека msimg32.dll содержит новые функции для получения соблазнительных графических эффектов. Для ее использования нужно подключить к проекту при сборке файл msimg32.lib.

Теперь растр с прозрачностью можно вывести за один прием с помощью функции TransparentBlt, указав прозрачный цвет в последнем параметре функции:

CDC memDC;

memDC.CreateCompatibleDC(pDC);

CBitmap *temp = memDC.SelectObject(m_Bmp)

TransparentBlt(pDC->m_hDC, x, y, dstX, dstY, memDC.m_hDC, x1, y1, srcX, srcY, RGB(255,255,255));

memDC.SelectObject(temp);

"Ничего себе – за один прием!" скажете вы и …будете правы. Вновь появляется необходимость в совместимом контексте устройства, в котором нужно выбрать выводимый растр. Вновь – длинный (и не интуитивный) список параметров. Но зато появились возможности по управлению выводом. В данном примере x, y, x1, y1 – координаты начальной точки растра в приемнике и источнике соответственно. Параметры dstX и dstY – размеры области вывода, а srcX и srcY – ширина и высота прямоугольника, отображаемого из растра. Что если задать для них разные значения? Результат приведен здесь.

Как видим, эта функция содержит возможности по сжатию/растяжению растровых изображений. Только не переусердствуйте и не передайте в качестве размеров отрицательные значения – зеркального отображения TransparentBlt создавать не умеет.

Добавим, что функция TransparentBlt при выводе опирается на возможности DirectX данного устройства, что может дать прирост производительности по сравнению с традиционными методами.

СОВЕТ

Не забудьте после использования контекста устройства вновь выбрать в нем начальный растр (temp в нашем примере). В противном случае произойдет утечка графических ресурсов системы.

AlphaBlend: "Полу" – не обязательно ½

Все вышеописанные методы работают только с одной моделью прозрачности, называемой в компьютерной

графике Chroma Key. Это означает, что прозрачным назначается определенный цвет. Другая, более развитая, модель называется Alpha Blending. При ее использовании для описания характеристик пикселов кроме цветовых компонент (R, G, B) применяется прозрачность (Alpha). Степень прозрачности определяется обратной величиной этого параметра.

Для поддержки этого режима Windows 98, а затем и Windows 2000 и Windows ME предоставляют функцию AlphaBlend:

BOOL AlphaBlend(HDC hdcDest, // handle to destination DC

 int nXOriginDest, // x-coord of upper-left corner

 int nYOriginDest, // y-coord of upper-left corner

 int nWidthDest, // destination width

 int nHeightDest, // destination height

 HDC hdcSrc, // handle to source DC

 int nXOriginSrc, // x-coord of upper-left corner

 int nYOriginSrc, // y-coord of upper-left corner

 int nWidthSrc, // source width

 int nHeightSrc, // source height BLENDFUNCTION

 blendFunction // alpha-blending function

);

Назначение ее параметров, в-общем, ясно из прототипа. Особый интерес представляет последний параметр – BLENDFUNCTION. Он представляет собой структуру (всего из четырех байт), определяющую режим вывода.

typedef struct _BLENDFUNCTION {

 BYTE BlendOp;

 BYTE BlendFlags;

 BYTE SourceConstantAlpha;

 BYTE AlphaFormat;

} BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;

Что это такое? Дело в том, что AlphaBlend может работать в двух разных режимах.

Простой режим (общая прозрачность)

Первый (и наиболее простой в использовании) режим работы AlphaBlend предполагает, что значение Alpha задано для всей картинки. В таком случае, оно применяется ко всем пикселам без исключения.

Формат BLENDFUNCTION в этом случае:

BLENDFUNCTION blend;

blend.BlendOp = AC_SRC_OVER;

blend.BlendFlags = 0;

blend.AlphaFormat = 0;

blend.SourceConstantAlpha = 180;

Для поля BlendOp в данный момент определено только одно допустимое значение — AC_SRC_OVER.

Поле BlendFlags должно содержать 0.

Плохо документированный параметр AlphaFormat определяет взаимодействие пикселов источника и приемника, о чем мы еще поговорим далее.

Параметр SourceConstantAlpha определяет степень непрозрачности. Задав для этого поля 0, вы не увидите свой растр вообще. Максимальное значение, умещающееся в тип BYTE, равно 255. При этом выводимый растр полностью перекроет область назначения. Но зачем вам, в таком случае, AlphaBlend? И это значение используется, в-основном, для второго режима.

Режим с альфа-каналом

Он требует некоторой дополнительной подготовки. В этом режиме растр, подготовленный для вывода, должен содержать информацию о степени прозрачности каждого пиксела. Это достигается, например, применением формата 32 бита на пиксел (по одному байту на каждый цветовой компонент и одному – на альфа-канал).

Поделиться с друзьями: