Поделиться через


Функция DrvAlphaBlend (winddi.h)

Функция DrvAlphaBlend предоставляет возможности передачи битовых блоков с помощью альфа-смешивания.

Синтаксис

BOOL DrvAlphaBlend(
  [in, out]      SURFOBJ  *psoDest,
  [in]           SURFOBJ  *psoSrc,
  [in]           CLIPOBJ  *pco,
  [in, optional] XLATEOBJ *pxlo,
  [in]           RECTL    *prclDest,
  [in]           RECTL    *prclSrc,
  [in]           BLENDOBJ *pBlendObj
);

Параметры

[in, out] psoDest

Указатель на структуру SURFOBJ , которая идентифицирует поверхность, на которой выполняется рисование.

[in] psoSrc

Указатель на структуру SURFOBJ, которая идентифицирует исходную поверхность.

[in] pco

Указатель на структуру CLIPOBJ . Подпрограммы службы CLIPOBJ_Xxx предоставляются для перечисления области клипа в виде набора прямоугольников. Это перечисление ограничивает область назначения, которая изменяется. По возможности GDI упрощает обрезку. Однако, в отличие от DrvBitBlt, DrvAlphaBlend может вызываться с одним прямоугольником, чтобы предотвратить ошибки округления при обрезке выходных данных.

[in, optional] pxlo

Указатель на структуру XLATEOBJ , которая указывает, как индексы цвета должны быть преобразованы между исходной и целевой поверхностями. Если pxlo имеет значение NULL, перевод не требуется.

Если исходная поверхность управляется палитрой, ее цвета представлены индексами в таблице подстановки значений цветов RGB. В этом случае XLATEOBJ можно запросить вектор преобразования, который позволяет драйверу устройства быстро преобразовать любой исходный индекс в цветовый индекс для назначения.

Ситуация сложнее, когда, например, источником является RGB, но назначение управляется палитрой. В этом случае наиболее близкое соответствие каждому исходному значению RGB должно находиться в конечной палитре. Драйвер может вызвать подпрограмму службы XLATEOBJ_iXlate для выполнения этой операции сопоставления.

[in] prclDest

Указатель на структуру RECTL , которая определяет прямоугольную область для изменения. Этот прямоугольник задается в системе координат целевой поверхности и определяется двумя точками: верхней левой и нижней правой. Две точки, определяющие прямоугольник, всегда хорошо упорядочены. Прямоугольник является эксклюзивным в нижнем правом углу; то есть его нижний и правый края не являются частью смеси.

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

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

[in] prclSrc

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

Исходный прямоугольник никогда не будет превышать границы исходной поверхности и поэтому никогда не будет нависать над исходной поверхностью.

DrvAlphaBlend никогда не вызывается с пустым исходным прямоугольником.

Сопоставление определяется с помощью prclSrc и prclDest. Точки, указанные в prclDest и prclSrc , находятся на целочисленных координатах, которые соответствуют пиксельным центрам. Прямоугольник, определенный двумя такими точками, считается геометрическим прямоугольником с двумя вершинами, координаты которых являются заданными точками, но с 0,5, вычитаемыми из каждой координаты. (Структуры POINTL представляют собой сокращенную нотацию для указания этих дробных вершин координат.)

[in] pBlendObj

Указатель на структуру BLENDOBJ , которая описывает операцию смешивания, выполняемую между исходной и целевой поверхностями. Эта структура является оболочкой для структуры BLENDFUNCTION, которая содержит необходимые сведения о формате источника и назначения, недоступные в XLATEOBJ. Структура BLENDFUNCTION определена в документации по Microsoft Windows SDK. Его члены определяются следующим образом:

BlendOp определяет выполняемую операцию смешения. В настоящее время это значение должно быть AC_SRC_OVER. Это означает, что исходное растровое изображение размещается над растровым изображением назначения на основе альфа-значений исходных пикселей. Существует три возможных случая, которые должна обрабатывать эта операция смешения. Они описаны в разделе Примечания.

BlendFlags зарезервирована и в настоящее время имеет нулевое значение.

SourceConstantAlpha определяет коэффициент смешения констант, применяемый ко всей исходной поверхности. Это значение находится в диапазоне [0,255], где 0 является полностью прозрачным, а 255 — полностью непрозрачным.

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

AC_SRC_ALPHA

Исходная поверхность может быть в предварительном формате альфа-32bpp "BGRA"; то есть тип поверхности — BMF_32BPP, а тип палитры — BI_RGB. Альфа-компонент — это целое число в диапазоне [0,255], где 0 является полностью прозрачным, а 255 — полностью непрозрачным.

Возвращаемое значение

DrvAlphaBlend возвращает значение TRUE при успешном выполнении. В противном случае он сообщает об ошибке и возвращает значение FALSE.

Комментарии

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

  • Из одной управляемой устройством поверхности в другую поверхность, управляемую устройством.
  • От одного битового изображения стандартного формата, управляемого GDI, к другому растрового изображения стандартного формата, управляемого GDI.
  • От одной управляемой устройством поверхности к управляемой GDI поверхности и наоборот.
Драйвер может выполнять вызовы к EngAlphaBlend.

Драйвер никогда не будет вызываться с перекрывающимися исходными и целевыми прямоугольниками на одной поверхности.

Ниже приведены три возможных варианта для функции AC_SRC_OVER blend.

  • Исходное растровое изображение не имеет альфа-канала для каждого пикселя (AC_SRC_ALPHA не задано), поэтому смесь применяется к цветовым каналам пикселя на основе постоянного исходного альфа-значения, указанного в SourceConstantAlpha, следующим образом:
    Dst.Red = Round(((Src.Red * SourceConstantAlpha) + 
        ((255 − SourceConstantAlpha) * Dst.Red)) / 255);
    Dst.Green = Round(((Src.Green * SourceConstantAlpha) + 
        ((255 − SourceConstantAlpha) * Dst.Green)) / 255);
    Dst.Blue = Round(((Src.Blue * SourceConstantAlpha) + 
        ((255 − SourceConstantAlpha) * Dst.Blue)) / 255);
    /* Do the next computation only if the destination bitmap 
        has an alpha channel. */
    Dst.Alpha = Round(((Src.Alpha * SourceConstantAlpha) + 
        ((255 − SourceConstantAlpha) * Dst.Alpha)) / 255);
    
  • Исходное растровое изображение имеет альфа-значения по пикселям (AC_SRC_ALPHA задано), а SourceConstantAlpha не используется (для него задано значение 255). Смесь вычисляется следующим образом:
    Dst.Red = Src.Red + 
        Round(((255 − Src.Alpha) * Dst.Red) / 255);
    Dst.Green = Src.Green + 
        Round(((255 − Src.Alpha) * Dst.Green) / 255);
    Dst.Blue = Src.Blue + 
        Round(((255 − Src.Alpha) * Dst.Blue) / 255);
    /* Do the next computation only if the destination bitmap 
        has an alpha channel. */
    Dst.Alpha = Src.Alpha + 
        Round(((255 − Src.Alpha) * Dst.Alpha) / 255);
    
  • Исходное растровое изображение имеет альфа-значения в пикселях (AC_SRC_ALPHA задано), и используется SourceConstantAlpha (не задано значение 255). Смесь вычисляется следующим образом:
    Temp.Red = Round((Src.Red * SourceConstantAlpha) / 255);
    Temp.Green = Round((Src.Green * SourceConstantAlpha) / 255);
    Temp.Blue = Round((Src.Blue * SourceConstantAlpha) / 255);
    /* The next computation must be done even if the 
        destination bitmap does not have an alpha channel. */
    Temp.Alpha = Round((Src.Alpha * SourceConstantAlpha) / 255);
     
    /* Note that the following equations use the just-computed 
       Temp.Alpha value: */
    Dst.Red = Temp.Red + 
        Round(((255 − Temp.Alpha) * Dst.Red) / 255);
    Dst.Green = Temp.Green + 
        Round(((255 − Temp.Alpha) * Dst.Green) / 255);
    Dst.Blue = Temp.Blue + 
        Round(((255 − Temp.Alpha) * Dst.Blue) / 255);
    /* Do the next computation only if the destination bitmap 
        has an alpha channel.  */
    Dst.Alpha = Temp.Alpha + 
        Round(((255 − Temp.Alpha) * Dst.Alpha) / 255);
    
Функция Round(x) округляется до ближайшего целого числа, вычисляемого как:
Trunc(x + 0.5);

При необходимости DrvAlphaBlend можно реализовать в графических драйверах. Он может быть предоставлен для обработки некоторых видов альфа-смешений, таких как смешения, где исходная и целевая поверхности имеют одинаковый формат и не содержат альфа-канал.

Аппаратная реализация может использовать плавающую или фиксированную точку в операции смешения. Тесты совместимости будут учитывать некоторые числовые ошибки в результатах; Сведения о максимально допустимой ошибке см. в разделе Специальные эффекты в драйверах дисплея. При использовании фиксированной точки допустимым приближением к термину x/255 является (x*257)/65536. Включив округление, выражение:

((255 - Src.Alpha) * Dst.Red) / 255

Затем можно приблизить к следующим значениям:

temp = ((255 - Src.Alpha) * Dst.Red) + 128;
result = (temp + (temp >> 8)) >> 8;

Драйвер перехватывает DrvAlphaBlend , устанавливая флаг HOOK_ALPHABLEND при вызове EngAssociateSurface. Если драйвер подключил DrvAlphaBlend и вызывается для выполнения операции, которая не поддерживается, драйвер должен иметь GDI для обработки операции путем отката данных в вызове EngAlphaBlend.

Требования

Требование Значение
Целевая платформа Персональный компьютер
Верхняя часть winddi.h (включая Winddi.h)

См. также раздел

DrvBitBlt

DrvPlgBlt

DrvStretchBlt

DrvStretchBltROP

DrvTransparentBlt

EngAlphaBlend

EngBitBlt

EngPlgBlt

EngStretchBlt

EngStretchBltROP

EngTransparentBlt