【学Rust写CAD】33 近似 Alpha 混合函数(argb.rs补充方法)

源码

#[inline]
    pub fn over(self, dst: Argb) -> Argb {
        let a = 256 - self.alpha32();
        let rb = (dst.rb() * a) >> 8;
        let ag = dst.ag() * a;
        Argb(self.0 + (rb & Argb::MASK) | (ag & !Argb::MASK))
    }

源码分析

这段代码实现了一个近似 Alpha 混合(“over” 操作)的函数,用于将一个半透明的颜色(self)覆盖在目标颜色(dst)之上。

关键点解析
  1. 近似方法:
  • 使用除以 256 的近似方法(通过右移 8 位实现)而不是更精确的除以 255

  • 这种近似方式与 Skia 图形库的 SKPMSrcOver 实现相同

  1. 参数:
  • self:源颜色(带 Alpha 通道的 ARGB 颜色)

  • dst:目标颜色(带 Alpha 通道的 ARGB 颜色)

  1. 计算步骤:
  • a = 256 - self.alpha32():计算源颜色的不透明度补数(1 - α)

  • rb = (dst.rb() * a) >> 8:对红蓝通道分量进行乘法并右移(近似除以 256)

  • ag = dst.ag() * a:对 Alpha 和绿通道分量进行乘法(注意这里没有右移)

  • 最后将源颜色与处理后的目标颜色组合起来

  1. 位操作:
  • rb & Argb::MASK:确保红蓝通道值在正确位置

  • ag & !Argb::MASK:确保 Alpha 和绿通道值在正确位置

  • 使用位或操作 | 将各部分组合起来

数学原理

这个函数实现了以下混合公式的近似:

result = src + dst × (1 - src_alpha)

但由于使用了除以 256 的近似而不是除以 255,在 Alpha 值为 255 时会有轻微误差。

性能考虑

  • 使用位操作和移位操作而不是除法,提高性能

  • 标记为 #[inline] 建议编译器内联此函数

  • 分离红蓝和 Alpha/绿通道处理,出于性能优化考虑

这种近似在大多数图形应用中视觉效果差异不大,但计算效率更高。

你可能感兴趣的:(学Rust写CAD,rust)