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

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

相关推荐
钟离墨笺3 小时前
Go语言--2go基础-->map
开发语言·后端·golang
Tony Bai3 小时前
Go 语言的“魔法”时刻:如何用 -toolexec 实现零侵入式自动插桩?
开发语言·后端·golang
qq_12498707535 小时前
基于小程序中医食谱推荐系统的设计(源码+论文+部署+安装)
java·spring boot·后端·微信小程序·小程序·毕业设计·计算机毕业设计
Marktowin6 小时前
SpringBoot项目的国际化流程
java·后端·springboot
程序员泠零澪回家种桔子6 小时前
RAG中的Embedding技术
人工智能·后端·ai·embedding
汤姆yu6 小时前
基于springboot的直播管理系统
java·spring boot·后端
a努力。6 小时前
虾皮Java面试被问:分布式Top K问题的解决方案
java·后端·云原生·面试·rpc·架构
饱饱要坚持可持续发展观7 小时前
SpringBoot 集成 Liquibase
java·spring boot·后端
我爱娃哈哈8 小时前
SpringBoot + MinIO + 阿里云 OSS:文件上传下载、分片断点续传全链路方案
spring boot·后端·阿里云
RunsenLIu8 小时前
基于Spring Boot + Vue的图书馆座位预约管理系统
vue.js·spring boot·后端