【学Rust写CAD】27 双线性插值函数(bilinear_interpolation.rs)

源码

rust 复制代码
use super::constant::BILINEAR_INTERPOLATION_BITS;
// Inspired by Filter_32_opaque from Skia.
fn bilinear_interpolation(
    tl: u32,
    tr: u32,
    bl: u32,
    br: u32,
    mut distx: u32,
    mut disty: u32,
) -> 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 >> 8) & 0xff00ff) | (hi & !0xff00ff)
}

代码分析

这个函数实现了双线性插值算法,用于在四个已知像素点(tl, tr, bl, br)之间插值计算一个新的像素值。该代码参考Skia图形库中Filter_32_opaque函数。

参数说明

  • tl: 左上(top-left)像素值

  • tr: 右上(top-right)像素值

  • bl: 左下(bottom-left)像素值

  • br: 右下(bottom-right)像素值

  • distx: x方向的插值距离(0-15)

  • disty: y方向的插值距离(0-15)

算法步骤

1.距离调整:

rust 复制代码
distx <<= 4 - BILINEAR_INTERPOLATION_BITS;
disty <<= 4 - BILINEAR_INTERPOLATION_BITS;

将输入的distx和disty从BILINEAR_INTERPOLATION_BITS精度调整到4位精度(0-15)。

  1. 计算权重因子:
  • distxy: distx * disty

  • distxiy: distx * (16 - disty)

  • distixy: disty * (16 - distx)
  • distixiy: (16 - distx) * (16 - disty)
  1. 分离颜色通道计算:
    函数将32位颜色值分为两个16位部分处理:
  • lo: 处理蓝色(低8位)和红色(高8位)通道

  • hi: 处理绿色(低8位)和alpha(高8位)通道

4.加权求和:

对四个角的像素值按照计算出的权重进行加权求和。

  1. 合并结果:
rust 复制代码
((lo >> 8) & 0xff00ff) | (hi & !0xff00ff)

将计算结果重新组合成32位像素值。

技术细节

  • 使用wrapping_操作防止中间计算溢出

  • 使用位操作高效处理颜色通道

  • 假设输入像素是不透明的(alpha通道为0xff)

这个函数在图像缩放、旋转等变换中非常有用,可以平滑地计算出新位置的像素值,避免锯齿效果。

相关推荐
用户490558160812535 分钟前
lvs会话同步
后端
用户490558160812536 分钟前
linux内核网络协议栈报文的处理过程
后端
夜宵饽饽36 分钟前
上下文工程实践 - 工具管理(上篇)
javascript·后端
ERP老兵_冷溪虎山38 分钟前
Python/JS/Go/Java同步学习(第十三篇)四语言“字符串转码解码“对照表: 财务“小南“纸式转码术处理凭证乱码崩溃(附源码/截图/参数表/避坑指南)
java·后端·python
努力的小郑42 分钟前
MySQL索引(四):深入剖析索引失效的原因与优化方案
后端·mysql·性能优化
智商偏低1 小时前
ASP.NET Core 中的简单授权
后端·asp.net
练习时长一年1 小时前
搭建langchain4j+SpringBoot的Ai项目
java·spring boot·后端
bobz9651 小时前
Proxmox qemu-server
后端
编码浪子1 小时前
趣味学RUST基础篇(异步补充)
开发语言·后端·rust
烈风1 小时前
003 cargo使用
rust·cargo