Rust图像处理第11节-故障风 RGB 通道偏移:错位错色制造电子故障

49 阅读5分钟

🦀 Rust + WASM 实战系列 第 11 篇 阅读时间:约 5 分钟 | 实战可运行

📌 写在前面

最后一篇邻域卷积,也是唯一一个不用卷积核的——靠像素坐标重映射就能实现"赛博朋克"风格。

原理极其简单:把 R、G、B 三个通道分别从不同位置取,自然就"错位"了。


🚀 TL;DR

原图:              故障风:
┌──────────┐       ┌──────────┐
│ R  G  B  │       │ R  G  B  │
│          │       │  ↑     ↑  │  ← R 向左偏移
│ RGB 像素  │  →   │   ↑     ↑ │  ← B 向右偏移
│          │       │  RGB 像素│
└──────────┘       └──────────┘
                    边缘出现"红/蓝重影"

两种模式

模式效果适用
horizontal整张图统一偏移轻微故障
random每行随机偏移(更乱)强故障

📖 目录

  1. 什么是 RGB 通道偏移?
  2. 核心算法:3 通道分别取不同位置
  3. 关键代码
  4. 前端效果展示
  5. 两种模式:uniform vs random
  6. 进阶:垂直偏移 / 颜色错位
  7. 应用场景

一、什么是 RGB 通道偏移?

一张图片 = 3 张灰度图叠在一起(R、G、B 各一张)。

正常情况:3 张叠得很准 → 一张彩色图。

R 通道:  ████ ████ ████      (红色位置)
G 通道:  ████ ████ ████      (绿色位置)← 对齐
B 通道:  ████ ████ ████      (蓝色位置)

结果:    彩色对齐 → "白衬衫"

RGB 偏移 = 把其中一两张错位

R 通道:   ████ ████           (向左移 2 格)
G 通道:   ████ ████ ████      (不动)
B 通道:        ████ ████      (向右移 2 格)

结果:    三层错位 → "红/蓝重影的赛博风"

视觉:边缘出现红边 + 蓝边,中间正常。


二、核心算法:3 通道分别取不同位置

// 原来:3 个通道都从 (x, y) 取
result[i]     = pixels[i]      // R
result[i + 1] = pixels[i + 1]  // G
result[i + 2] = pixels[i + 2]  // B

// 现在:R、B 从不同位置取
result[i]     = pixels[(y * w + (x - off)) * 4]      // R 从左边 off 像素取
result[i + 1] = pixels[i + 1]                       // G 保持
result[i + 2] = pixels[(y * w + (x + off)) * 4 + 2]  // B 从右边 off 像素取

就这么简单——没有卷积核,没有梯度,纯坐标重映射


三、关键代码

for y in 0..h {
    let row_off = if kind == "random" {
        // 每行用伪随机偏移
        (pseudo_rand(y as u32, 0, 42) as i32 % (off * 2 + 1)) - off
    } else {
        off
    };

    for x in 0..w {
        let out = ((y * w + x) * 4) as usize;

        // R:向左偏 row_off
        let r_x = (x - row_off).clamp(0, w - 1);
        let r_idx = ((y * w + r_x) * 4) as usize;
        result[out] = pixels[r_idx];

        // G:保持
        result[out + 1] = pixels[out + 1];

        // B:向右偏 row_off
        let b_x = (x + row_off).clamp(0, w - 1);
        let b_idx = ((y * w + b_x) * 4) as usize;
        result[out + 2] = pixels[b_idx + 2];

        // A:保持
        result[out + 3] = pixels[out + 3];
    }
}

四、前端效果展示

a25d763f-2b71-40fd-a0d4-e91ca7058a8e.png

五、两种模式:uniform vs random

uniform 模式

let row_off = off;  // 每行都用同一个偏移

效果:整张图"红蓝"整齐地错位,比较"克制"。

random 模式(更故障)

let row_off = pseudo_rand(y, 0, 42) % (off * 2 + 1) - off;
//                ↑             ↑
//                0~255        映射到 -off ~ +off

效果:每行错位量不同,看起来像"真·信号故障"。

模式视觉效果
horizontal整齐错位(轻微)
random撕裂错位(强烈)

六、进阶:垂直偏移 / 颜色错位

垂直偏移

x ± off 改成 y ± off,整张图变成"上下错位":

// R 从上面取
let r_y = (y - off).clamp(0, h - 1);
let r_idx = ((r_y * w + x) * 4) as usize;
result[out] = pixels[r_idx];

// B 从下面取
let b_y = (y + off).clamp(0, h - 1);
let b_idx = ((b_y * w + x) * 4 + 2) as usize;
result[out + 2] = pixels[b_idx + 2];

三通道独立偏移

不只偏 R 和 B,三个通道各偏不同方向

result[out]     = pixels[((y * w + (x - off))     * 4)];      // R 左
result[out + 1] = pixels[((y * w + (x + off / 2)) * 4 + 1)]; // G 轻微右
result[out + 2] = pixels[((y * w + (x + off))     * 4 + 2)];  // B 右

效果更"乱",故障感更强。


七、应用场景

场景说明
赛博朋克风格黑客帝国 / 银翼杀手
音乐 MV80s / Synthwave 风格
故障艺术(Glitch Art)当代艺术常用手法
复古游戏 UI老电视 / 录像带质感
恐怖游戏"信号被干扰" 的诡异效果
VHS 滤镜模拟老录像带
品牌 Logo 设计抖音 / TikTok 音符图标的视觉签名

🎵 抖音 / TikTok 图标:克制的 RGB 偏移

最经典也最被忽视的例子 —— 抖音 / TikTok 的音符图标

┌─────────────────┐
│                 │
│      ╱╲         │
│     ╱  ╲        │   ← 音符主体(白色)
│    ╱    ╲       │
│   ╱      ●      │   ← 音符头(白色)
│  ╱              │
│                 │
└─────────────────┘

仔细看音符边缘,会发现有轻微的红 / 青(cyan)色"重影"——这就是 RGB 通道偏移的视觉签名:

抖音图标边缘RGB 通道偏移效果
红色重影在一侧R 通道偏移
青色(= 缺 R)重影在另一侧B 通道偏移
中心正常G 通道保持

本质上就是同一个算法——只是抖音用得很"克制"(偏移 12 像素,作为品牌识别的微妙细节),而故障风用得很"放肆"(偏移 1030 像素,做强烈的赛博朋克风格)。

为什么 TikTok 选这个风格?

  1. 辨识度:RGB 分离让人一眼就能"看见"图像边界,比纯白色音符更有视觉张力
  2. 时代感:呼应短视频时代的"快、躁、潮"调性
  3. 年轻化:红 / 青撞色是赛博朋克、Synthwave 文化的标志色
  4. 普适性:在手机小图标(48×48)和大 banner 上都能保持识别度

💡 设计圈的小秘密:很多设计师做故障风时先做"大偏移"找灵感,再缩到"小偏移"做成品牌 logo——同一个数学公式,只是参数不同。理解了这个,你也能复刻任何"赛博朋克 logo"。


🎁 写在最后

第二部分"邻域卷积"全完结 🎉

任务核数输出
6 模糊1平滑
7 马赛克0块状
8 暗角0四周变暗
9 Sobel2边缘
10 浮雕1立体感
11 RGB 偏移0错位重影

所有 6 个都用到了 nalgebra 或类似工具——你已经彻底掌握邻域操作了。

下部分预告:第三部分 图像几何变换——用 2D 矩阵做旋转、缩放、翻转线代工具箱正式登场


📦 项目地址pixel-math-wasm 🦀 Rust + WebAssembly 实战系列


🏷️ 标签#Rust #WebAssembly #图像处理 #RGB偏移 #故障风 #赛博朋克 #算法