drvAlphaBlend 函数 (winddi.h)

DrvAlphaBlend 函数通过 alpha 混合提供位块传输功能。

语法

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 结构的指针,该结构指定如何在源图面和目标图面之间转换颜色索引。 如果 pxloNULL,则无需转换。

如果源图面由调色板管理,则其颜色由索引表示为 RGB 颜色值的查阅表中。 在这种情况下,可以查询 XLATEOBJ 以获取转换向量,该向量允许设备驱动程序快速将任何源索引转换为目标的颜色索引。

例如,当源为 RGB,但目标由调色板管理时,情况会更加复杂。 在这种情况下,必须在目标调色板中找到与每个源 RGB 值最接近的匹配项。 驱动程序可以调用 XLATEOBJ_iXlate 服务例程来执行此匹配操作。

[in] prclDest

指向 RECTL 结构的指针,该结构定义要修改的矩形区域。 此矩形在目标图面的坐标系中指定,由两个点定义:左上角和右下角。 定义矩形的两个点始终有序。 矩形在右下角是独占的;也就是说,其下边缘和右边缘不是混合的一部分。

在写入像素时,驱动程序应小心进行适当的剪裁,因为指定的矩形可能会悬停在目标图面上。

永远不会使用空的目标矩形调用 DrvAlphaBlend

[in] prclSrc

指向 RECTL 结构的指针,该结构定义要复制的区域。 此矩形在源图面的坐标系中指定,由两个点定义:左上角和右下角。 定义矩形的两个点始终有序。 矩形在右下角是独占的;也就是说,其下边缘和右边缘不是混合的一部分。

源矩形永远不会超过源图面的边界,因此永远不会悬停源图面。

从不使用空源矩形调用 DrvAlphaBlend

映射由 prclSrcprclDest 定义。 prclDestprclSrc 中指定的点位于对应于像素中心的整数坐标上。 由两个此类点定义的矩形被视为具有两个顶点的几何矩形,其坐标是给定点,但从每个坐标中减去 0.5。 (POINTL 结构是用于指定这些小数坐标顶点的简写表示法。)

[in] pBlendObj

指向 BLENDOBJ 结构的指针,该结构描述在源图面和目标图面之间执行的混合操作。 此结构是 BLENDFUNCTION 结构的包装器,其中包括 XLATEOBJ 中不可用的必要源和目标格式信息。 BLENDFUNCTION 结构在Microsoft Windows SDK文档中定义。 其成员定义如下:

BlendOp 定义要执行的混合操作。 目前,此值必须AC_SRC_OVER,这意味着源位图基于源像素的 alpha 值放置在目标位图上。 此混合操作应处理三种可能的情况。 “备注”部分介绍了这些内容。

BlendFlags 是保留的,当前设置为零。

SourceConstantAlpha 定义应用于整个源图面的常量混合因子。 此值在 [0,255] 的范围内,其中 0 是完全透明的,255 是完全不透明的。

AlphaFormat 定义是否假定图面具有 alpha 通道。 可以选择将此成员设置为以下值:

AC_SRC_ALPHA

可以假定源图面采用预乘 alpha 32bpp“BGRA”格式;也就是说,图面类型为BMF_32BPP,调色板类型为BI_RGB。 alpha 分量是 [0,255] 范围内的整数,其中 0 是完全透明的,255 是完全不透明的。

返回值

DrvAlphaBlend 成功后返回 TRUE 。 否则,它将报告错误并返回 FALSE

注解

驱动程序可以在以下图面之间通过 alpha 混合支持位块传输:

  • 从一个 设备管理图面 到另一个设备托管图面。
  • 从一个 GDI 管理的标准格式位图到另一个 GDI 管理的标准格式位图。
  • 从一个设备管理的表面到 GDI 托管的图面,反之亦然。
驱动程序可以打断对 EngAlphaBlend 的调用。

驱动程序永远不会在同一图面上使用重叠的源矩形和目标矩形调用。

AC_SRC_OVER blend 函数的三种可能情况是:

  • 源位图没有每像素 alpha (AC_SRC_ALPHA 未) 设置,因此,根据 SourceConstantAlpha 中指定的常量源 alpha 值将混合应用于像素的颜色通道,如下所示:
    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);
    
  • 源位图具有每像素 alpha 值, (AC_SRC_ALPHA 设置为) , (设置为 255) ,则不使用 SourceConstantAlpha 。 混合的计算方式如下:
    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);
    
  • 源位图具有每像素 alpha 值 (AC_SRC_ALPHA 设置为) , (未设置为 255) ,则使用 SourceConstantAlpha 。 混合的计算方式如下:
    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。 可以提供它来处理某些类型的 alpha 混合,例如源图面和目标图面格式相同且不包含 alpha 通道的混合。

硬件实现可以在混合操作中使用浮点或定点。 兼容性测试将考虑结果中的一些数字错误;有关最大允许错误的信息,请参阅 显示驱动程序中的特殊效果 。 使用定点时,与术语 x/255 的可接受近似值 (x*257) /65536。 合并舍入,表达式:

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

然后可以近似为:

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

驱动程序通过在调用 EngAssociateSurface 时设置 HOOK_ALPHABLEND 标志来挂钩 DrvAlphaBlend。 如果驱动程序已挂钩 DrvAlphaBlend 并被调用以执行它不支持的操作,则驱动程序应让 GDI 通过在调用 EngAlphaBlend 时插入数据来处理该操作。

要求

要求
目标平台 桌面
标头 winddi.h (包括 Winddi.h)

另请参阅

DrvBitBlt

DrvPlgBlt

DrvStretchBlt

DrvStretchBltROP

DrvTransparentBlt

EngAlphaBlend

EngBitBlt

EngPlgBlt

EngStretchBlt

EngStretchBltROP

EngTransparentBlt