源码
rust
use super::constant::BILINEAR_INTERPOLATION_BITS;
// Inspired by Filter_32_alpha from Skia.
fn bilinear_interpolation_alpha(
tl: u32,
tr: u32,
bl: u32,
br: u32,
mut distx: u32,
mut disty: u32,
alpha: Alpha256
) -> u32 {
let distxy;
let distxiy;
let distixy;
let distixiy;
let mut lo;
let mut hi;
distx <<= 4 - BILINEAR_INTERPOLATION_BITS;
disty <<= 4 - BILINEAR_INTERPOLATION_BITS;
distxy = distx * disty;
distxiy = (distx << 4) - distxy; // distx * (16 - disty)
distixy = (disty << 4) - distxy; // disty * (16 - distx)
// (16 - distx) * (16 - disty)
// The intermediate calculation can underflow so we use
// wrapping arithmetic to let the compiler know that it's ok
distixiy = (16u32 * 16)
.wrapping_sub(disty << 4)
.wrapping_sub(distx << 4)
.wrapping_add(distxy);
lo = (tl & 0xff00ff) * distixiy;
hi = ((tl >> 8) & 0xff00ff) * distixiy;
lo += (tr & 0xff00ff) * distxiy;
hi += ((tr >> 8) & 0xff00ff) * distxiy;
lo += (bl & 0xff00ff) * distixy;
hi += ((bl >> 8) & 0xff00ff) * distixy;
lo += (br & 0xff00ff) * distxy;
hi += ((br >> 8) & 0xff00ff) * distxy;
lo = ((lo >> 8) & 0xff00ff) * alpha;
hi = ((hi >> 8) & 0xff00ff) * alpha;
((lo >> 8) & 0xff00ff) | (hi & !0xff00ff)
}
代码分析
这个函数是前一个双线性插值函数的扩展版本,增加了对 Alpha 通道(透明度)的支持。它同样参考 Skia 图形库中 Filter_32_alpha 函数。
新增参数说明
alpha: 一个额外的透明度参数(Alpha256 类型),范围应该是 0-256,用于控制最终结果的透明度
与之前版本的主要区别
- Alpha 混合:
- 在计算完所有颜色通道后,额外进行了 Alpha 混合操作:
rust
lo = ((lo >> 8) & 0xff00ff) * alpha;
hi = ((hi >> 8) & 0xff00ff) * alpha;
- 这使得结果颜色会按照给定的 alpha 值进行透明度混合
- 颜色通道处理:
-
保持与前一个函数相同的颜色通道分离处理方式:
-
lo: 处理蓝色和红色通道
-
hi: 处理绿色和 Alpha 通道
-
算法流程
- 距离调整(与前一个函数相同):
- 调整 distx 和 disty 到 4 位精度
- 计算权重因子(与前一个函数相同):
- distxy, distxiy, distixy, distixiy
- 颜色加权求和(与前一个函数相同):
- 对四个角的像素值进行加权混合
- Alpha 混合(新增):
-
将计算结果与给定的 alpha 值相乘
-
这使得可以实现半透明效果
- 最终组合:
- 将处理后的颜色通道重新组合成 32 位像素值
技术细节
-
仍然使用 wrapping 运算防止溢出
-
Alpha 值范围是 0-256(而不是传统的 0-255),这可能是为了优化计算效率
-
保持了高效的颜色通道分离处理方式
这个函数适用于需要透明度混合的图像处理场景,如半透明图层叠加、渐变效果等。通过额外的 alpha 参数,可以灵活控制插值结果的透明度。