【学Rust写CAD】39 over_in_in 函数(alpha256补充方法)
源码
// Similar to over_in but includes an additional clip alpha value
#[inline]
pub fn over_in_in(self,src: Argb, dst: Argb, clip: Alpha) -> Argb {
let src_alpha = self * clip;
let dst_alpha = !(src_alpha*src.alpha_t());
// we sum src and dst before reducing to 8 bit to avoid accumulating rounding errors
Argb::from_ag_rb_div256(
src.ag() * src_alpha.0 + dst.ag() * dst_alpha.0 ,
src.rb() * src_alpha.0 +dst.rb() * dst_alpha.0
)
}
代码分析
over_in_in 是 over_in 函数的扩展版本,增加了额外的裁剪 alpha 值 (clip) 参数,用于更精细地控制合成操作。
功能
-
执行带双重 alpha 控制的合成操作:src over dst
-
使用两个 alpha 控制参数:
-
self:基础 alpha 因子
-
clip:额外的裁剪 alpha 值
-
-
在 16 位精度下进行中间计算,减少舍入误差累积
-
最终结果通过近似除以 256 来优化性能
代码解析
#[inline] // 内联优化标记
pub fn over_in_in(self, src: Argb, dst: Argb, clip: Alpha) -> Argb {
// 计算最终的源 alpha 值 = self * clip
let src_alpha = self * clip;
// 计算目标的 alpha 因子 = 1 - (src_alpha * src 的 alpha 通道)
let dst_alpha = !(src_alpha * src.alpha_t());
// 在 16 位精度下进行分量乘法和加法,最后才降为 8 位
Argb::from_ag_rb_div256(
src.ag() * src_alpha.0 + dst.ag() * dst_alpha.0, // alpha 和绿色通道
src.rb() * src_alpha.0 + dst.rb() * dst_alpha.0 // 红色和蓝色通道
)
}
关键点
- 双重 alpha 控制:
-
通过 self 和 clip 两个参数提供更灵活的 alpha 控制
-
最终源 alpha = self * clip
- 目标 alpha 计算:
-
使用 ! 运算符计算 256 - alpha(补运算)
-
考虑了源图像的 alpha 通道 (src.alpha_t())
- 精度优化:
-
在 16 位空间进行中间计算,避免 8 位计算的舍入误差累积
-
最后才通过 from_ag_rb_div256 降为 8 位
- 性能优化:
-
使用 #[inline] 提示编译器内联
-
同时处理多个颜色通道(红蓝一起,alpha 绿一起)
-
使用近似除以 256 代替精确除以 255
- 数学原理:
-
实现了公式:result = src * (self * clip) + dst * (256 - (self * clip * src_alpha))
-
比标准 alpha 合成更通用,允许额外的 alpha 控制
这个函数特别适合需要多层 alpha 控制的复杂合成场景,如带遮罩的图形渲染或 UI 元素的渐进显示效果。