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

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

相关推荐
雨雨雨雨雨别下啦5 分钟前
Spring AOP概念
java·后端·spring
on the way 1236 分钟前
day04-Spring之Bean的生命周期
java·后端·spring
代码笔耕8 分钟前
面向对象开发实践之消息中心设计(二)
java·后端·架构
云水木石16 分钟前
Rust 语言开发的 Linux 桌面来了
linux·运维·开发语言·后端·rust
法欧特斯卡雷特22 分钟前
Kotlin 2.3.0 现已发布!又有什么好东西?
后端·架构·开源
a努力。38 分钟前
小红书Java面试被问:ThreadLocal 内存泄漏问题及解决方案
java·jvm·后端·算法·面试·架构
serendipity_hky43 分钟前
【go语言 | 第4篇】goroutine模型和调度策略
后端·性能优化·golang
狂炫冰美式1 小时前
《预言市场进化论:从罗马斗兽场,到 Polymarket 的 K 线图》
前端·后端
Source.Liu1 小时前
【time-rs】解释://! Invalid format description(error/invalid_format_description.rs)
rust·time
fegggye1 小时前
创建一个rust写的python库[signatures和错误处理]
开发语言·python·rust