源码
rust
#[derive(Clone, Copy)]
pub struct Alpha256(u32);
impl Alpha256{
#[inline]
pub fn from(alpha:u32)->Alpha256{
Alpha256(alpha+1)
}
// Calculates 256 - (value * alpha256) / 255 in range [0,256],
// for [0,255] value and [0,256] alpha256.
#[inline]
fn alpha_mul_inv256(self,value: u32) -> u32 {
let prod = value * self.0;
256 - ((prod + (prod >> 8)) >> 8)
}
// Calculates (value * alpha256) / 255 in range [0,256],
// for [0,255] value and [0,256] alpha256.
fn alpha_mul_256(self,value: u32) -> u32 {
let prod = value * self.0;
(prod + (prod >> 8)) >> 8
}
}
源码分析
代码定义了一个名为 Alpha256 的结构体,用于处理与透明度(alpha)相关的计算。以下是对代码的逐步解释:
- 结构体定义
rust
#[derive(Clone, Copy)]
pub struct Alpha256(u32);
Alpha256 是一个简单的包装类型,内部包含一个 u32 值。
#[derive(Clone, Copy)] 表示该结构体可以自动实现 Clone 和 Copy trait,因此它可以被复制(按位拷贝)而无需移动所有权。
- 构造函数
rust
#[inline]
pub fn from(alpha: u32) -> Alpha256 {
Alpha256(alpha + 1)
}
from 是一个构造函数,接受一个 u32 参数 alpha,并返回 Alpha256 实例。
设计意图是将输入的 alpha 范围从 [0, 255] 转换为 [1, 256](避免除零或无效计算)。
- 方法:alpha_mul_inv256
rust
#[inline]
fn alpha_mul_inv256(self, value: u32) -> u32 {
let prod = value * self.0;
256 - ((prod + (prod >> 8)) >> 8)
}
-
功能:计算 256 - (value * alpha256) / 255,结果范围在 [0, 256]。
-
输入:
-
value:范围 [0, 255] 的像素值。
-
self.0:范围 [1, 256] 的 alpha 值(由构造函数保证)。
-
计算过程:
-
prod = value * self.0:先计算原始乘积(范围 [0, 255 * 256])。
-
(prod + (prod >> 8)) >> 8:这是快速近似除以 255 的技巧:
-
prod >> 8 等价于 prod / 256。
-
prod + (prod >> 8) 近似于 prod * (1 + 1/256),即 prod * 257/256。
-
右移 8 位(>> 8)相当于除以 256,因此最终结果为 (prod * 257) / 65536 ≈ prod / 254.98(接近 prod / 255)。
- 256 - ...:计算补值,得到反向的 alpha 混合结果。
- 用途:用于"反向混合"计算(如 1 - alpha 的效果)。
- 方法:alpha_mul_256
rust
fn alpha_mul_256(self, value: u32) -> u32 {
let prod = value * self.0;
(prod + (prod >> 8)) >> 8
}
-
功能:计算 (value * alpha256) / 255,结果范围在 [0, 256]。
-
输入:与 alpha_mul_inv256 相同。
-
计算过程:
- 和 alpha_mul_inv256 的前半部分完全一致,只是没有最后的 256 - ... 步骤。
-
用途:直接计算 alpha 混合后的值(例如 value * (alpha / 255))。
关键点
- 快速除以 255 的近似:
-
公式 (prod + (prod >> 8)) >> 8 是优化技巧,避免了昂贵的除法操作。
-
误差分析:对于 prod = 255 * 256,真实值为 256,而计算结果为 (65280 + 255) >> 8 = 255(误差 1/256)。
- Alpha 范围:
- 构造函数将输入 alpha 从 [0, 255] 映射到 [1, 256],是为了避免 alpha = 0 时的无效计算。
- 用途:
- 这些方法通常用于图像处理中的透明度混合(如 blend = foreground * alpha + background * (1 - alpha))。