【学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)

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

相关推荐
是发财不是旺财24 分钟前
跟着deepseek学golang--认识golang
开发语言·后端·golang
我的golang之路果然有问题24 分钟前
快速上手GO的net/http包,个人学习笔记
笔记·后端·学习·http·golang·go·net
Apifox.26 分钟前
Apifox 4月更新|Apifox在线文档支持LLMs.txt、评论支持使用@提及成员、支持为团队配置「IP 允许访问名单」
前端·人工智能·后端·ai·ai编程
BXCQ_xuan1 小时前
基于Node.js的健身会员管理系统的后端开发实践
后端·mysql·node.js
拉满buff搞代码2 小时前
搞定 PDF“膨胀”难题:Python + Java 的超实用压缩秘籍
后端
FAQEW2 小时前
Spring boot 中的IOC容器对Bean的管理
java·spring boot·后端·bean·ioc容器
红尘散仙2 小时前
六、WebGPU 基础入门——Vertex 缓冲区和 Index 缓冲区
前端·rust·gpu
<<2 小时前
基于Django的权限管理平台
后端·python·django
苏近之2 小时前
深入浅出 Rust 异步运行时原理
rust·源码
林夕11202 小时前
颠覆认知的MySQL全解析:安装、连接到SQL三大核心语句全掌握
后端·mysql