【学Rust写CAD】30 Argb结构乘Alpha256(Argb.rs 乘法重载)
源码
use std::ops::Mul; // 导入标准库的乘法 trait
use alpha::Alpha256; // 使用 Alpha256 类型
// 为 Argb 实现 Mul<Alpha256>,即支持 Argb * Alpha256 运算
impl Mul<Alpha256> for Argb {
type Output = Argb; // 指定乘法结果的类型为 Argb
#[inline] // 建议编译器内联优化
fn mul(self, a: Alpha256) -> Argb {
// 实际计算:对颜色分量进行透明度乘法
Argb::from_ag_rb_div256(self.ag() * a.0, self.rb() * a.0)
}
}
代码分析
这段代码为 Argb 类型实现了乘法运算符 * 的重载,使其能够与 Alpha256 类型相乘,用于颜色与透明度的混合计算。以下是详细解释:
关键组件说明
- Mul Trait
-
来自 std::ops::Mul,用于重载 * 运算符。
-
需定义关联类型 Output 和 mul 方法。
- Alpha256
- 表示透明度的类型,范围 [0, 256](a.0 访问内部值)。
- Argb::from_ag_rb_div256
-
构造函数,用于从预乘后的分量重建颜色。
-
参数:
-
self.ag() * a.0:Alpha 和 Green 分量 × 透明度。
-
self.rb() * a.0:Red 和 Blue 分量 × 透明度。
-
-
_div256 暗示内部进行右移 8 位(等价于除以 256),将结果缩放回 8 位。
运算逻辑
- 颜色分量分离
-
self.ag():提取 Alpha 和 Green 通道(如 0xAA00GG 格式)。
-
self.rb():提取 Red 和 Blue 通道(如 0xRR00BB 格式)。
预乘 Alpha(Premultiplied Alpha)
各分量乘以透明度 a.0,实现颜色与透明度的混合:
R' = R * (a / 256)
G' = G * (a / 256)
B' = B * (a / 256)
A' = A * (a / 256)
- 结果重组
- from_ag_rb_div256 将乘积结果重新打包为 Argb 格式,包含除法/位移优化。
使用示例
let color = Argb(0x80FF0000); // 半透明红色 (A=0x80, R=0xFF)
let alpha = Alpha256(128); // 透明度 128/256 = 0.5
let blended = color * alpha; // 结果为 0x40800000 (A=0x40, R=0x80)
为什么需要这种实现?
- 性能优化
-
使用整数运算和位操作,避免浮点计算。
-
#[inline] 提升小函数调用效率。
- 语义清晰
- color * alpha 比显式调用 alpha_mul(color, alpha) 更直观。
- 与其他代码兼容
- 符合 Rust 运算符重载惯例,可无缝集成到数学表达式中。
注意事项
-
分量顺序依赖:假设 ag() 和 rb() 返回的分量顺序与 from_ag_rb_div256 匹配。
-
溢出风险:乘法前需确保分量类型足够宽(如 u16 或 u32)。
-
Alpha 范围:Alpha256(256) 表示完全不透明,Alpha256(0) 表示完全透明。