<!-- title: Claude Code + WASM图像处理：Rust到浏览器全实战 -->

# Claude Code + WebAssembly图像处理：Rust到浏览器全链路实战

**学习目标**：使用Claude Code从零构建一个高性能WebAssembly图像处理应用。你将学会如何让Claude Code辅助完成Rust核心算法编写、wasm-bindgen桥接、前端Canvas集成、性能基准测试和生产部署的完整流程。项目最终实现灰度化、高斯模糊、边缘检测、亮度调节四种图像滤镜，WASM引擎比纯JavaScript快5-10倍。

**适用人群**：有基本前端开发经验、想尝试WebAssembly的前端工程师；或想了解Claude Code如何辅助Rust+WASM全栈开发的后端开发者。无需Rust基础——Claude Code会帮你写。

---

## 前置条件

| 工具 | 版本要求 | 安装方式 |
|------|---------|---------|
| Node.js | ≥ 18 | `nvm install 18 && nvm use 18` |
| Rust | stable ≥ 1.75 | `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \| sh` |
| wasm-pack | ≥ 0.13 | `cargo install wasm-pack` |
| Claude Code | ≥ 1.0 | `npm install -g @anthropic-ai/claude-code` |
| 浏览器 | Chrome/Firefox ≥ 90 | 支持WASM + Canvas |

验证环境：

```bash
rustc --version && cargo --version && wasm-pack --version && claude --version
```

---

## 架构全景

在开始编码之前，理解整个项目的架构至关重要：

```mermaid
graph TB
    subgraph "开发阶段（Claude Code辅助）"
        A[CLAUDE.md<br/>项目配置] --> B[Rust Core<br/>lib.rs - 图像处理算法]
        A --> C[Cargo.toml<br/>WASM编译配置]
        B --> D[wasm-bindgen<br/>Rust↔JS桥接层]
        D --> E[wasm-pack build<br/>编译输出pkg/]
    end

    subgraph "运行时架构"
        F[HTML页面<br/>文件上传 + Canvas] --> G[JavaScript<br/>读取ImageData]
        G --> H{Web Worker}
        H -->|postMessage| I[WASM模块<br/>Rust编译的.wasm]
        I -->|处理结果| H
        H -->|结果回传| G
        G --> J[Canvas渲染<br/>显示处理后图像]
    end

    E --> I

    style A fill:#f9f,stroke:#333
    style I fill:#ff9,stroke:#333
    style J fill:#9f9,stroke:#333
```

关键设计决策：

1. **Rust核心层**：纯计算逻辑，不依赖任何浏览器API，方便单元测试
2. **wasm-bindgen桥接**：只在边界层做类型转换，保持核心纯净
3. **Web Worker隔离**：图像处理不阻塞UI主线程
4. **Canvas直出**：处理完的像素数据直接写入Canvas，无需中间格式转换

---

## 第一步：项目初始化

打开终端，创建项目目录并启动Claude Code：

```bash
mkdir wasm-image-lab && cd wasm-image-lab
claude
```

### 配置CLAUDE.md

在Claude Code交互中，让它帮你创建项目级的 `CLAUDE.md`：

```
请帮我创建本项目的 CLAUDE.md 文件。这是一个 Rust + WebAssembly 图像处理项目，
要求包含以下指导信息：
- 本项目使用 wasm-pack 构建，target 是 web
- Rust 代码放在 src/lib.rs，是 cdylib 类型的库
- 依赖包括 wasm-bindgen, web-sys, js-sys, console_error_panic_hook
- 构建命令: wasm-pack build --target web --out-dir pkg
- 测试命令: wasm-pack test --chrome
- 代码风格：优先使用迭代器而非 for 循环，错误处理用 Result 而非 panic
- 前端使用原生 HTML/CSS/JS，不使用任何框架
```

Claude Code 会生成类似这样的 `CLAUDE.md`：

```markdown
# WASM Image Lab

高性能 WebAssembly 图像处理应用

## 构建命令
- 构建 WASM: `wasm-pack build --target web --out-dir pkg`
- 运行测试: `wasm-pack test --chrome`
- 本地预览: `python3 -m http.server 8080`

## 技术栈
- Rust (cdylib) → wasm-pack → WebAssembly
- wasm-bindgen + web-sys + js-sys
- 原生 HTML5 Canvas

## 代码规范
- 优先使用迭代器和函数式风格
- 所有公共 API 返回 Result 类型
- 使用 #[wasm_bindgen] 标注导出函数
- 使用 console_error_panic_hook 捕获 Rust panic

## 项目结构
src/lib.rs     - Rust 核心图像处理算法
pkg/           - wasm-pack 输出目录
www/           - 前端静态文件（HTML/JS/CSS）
```

### 初始化Rust项目

在Claude Code中继续：

```
请帮我初始化这个 Rust WASM 项目的 Cargo.toml 和 src/lib.rs。
项目名称 wasm-image-lab，crate-type 为 cdylib。
依赖：wasm-bindgen 0.2, web-sys 0.3 (features: HtmlCanvasElement, CanvasRenderingContext2d, ImageData, Window, Document), js-sys 0.3, console_error_panic_hook 0.1
```

Claude Code会生成 `Cargo.toml`：

```toml
[package]
name = "wasm-image-lab"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
wasm-bindgen = "0.2"
js-sys = "0.3"
console_error_panic_hook = "0.1"

[dependencies.web-sys]
version = "0.3"
features = [
    "HtmlCanvasElement",
    "CanvasRenderingContext2d",
    "ImageData",
    "Window",
    "Document",
]

[dev-dependencies]
wasm-bindgen-test = "0.3"

[profile.release]
opt-level = "z"     # 最小体积
lto = true          # 链接时优化
codegen-units = 1   # 单编译单元，更激进的优化
```

以及 `src/lib.rs` 骨架：

```rust
use wasm_bindgen::prelude::*;

// 安装 panic hook，让 Rust 的 panic 信息输出到浏览器控制台
#[wasm_bindgen(start)]
pub fn init() {
    console_error_panic_hook::set_once();
}

/// 像素数据结构：RGBA 四通道
#[derive(Clone, Copy)]
struct Pixel {
    r: u8,
    g: u8,
    b: u8,
    a: u8,
}

/// 从原始字节数组解析为像素向量
fn bytes_to_pixels(data: &[u8]) -> Vec<Pixel> {
    data.chunks_exact(4)
        .map(|chunk| Pixel {
            r: chunk[0],
            g: chunk[1],
            b: chunk[2],
            a: chunk[3],
        })
        .collect()
}

/// 像素向量转回字节数组
fn pixels_to_bytes(pixels: &[Pixel]) -> Vec<u8> {
    pixels.iter().flat_map(|p| [p.r, p.g, p.b, p.a]).collect()
}
```

**预期结果**：项目目录包含 `Cargo.toml`、`src/lib.rs`、`CLAUDE.md` 三个核心文件。运行 `cargo check` 能通过编译检查。

**常见问题**：
- **`wasm-bindgen` 版本冲突**：确保 `wasm-bindgen` 的 crate 版本与 CLI 工具版本匹配。用 `cargo install wasm-bindgen-cli --version 0.2.$VERSION` 安装对应版本。
- **`web-sys` features 缺失**：编译时如果提示某类型未定义，需要在 `Cargo.toml` 的 features 列表中添加对应 feature 名。Claude Code会根据报错自动补全。

---

## 第二步：核心图像处理算法

在Claude Code中输入以下prompt来生成核心算法：

```
请在 src/lib.rs 中实现以下四个图像处理函数，每个函数都导出为 #[wasm_bindgen]：

1. grayscale(input: &[u8], width: u32, height: u32) -> Vec<u8>
   - 使用 ITU-R BT.601 标准加权：0.299R + 0.587G + 0.114B
   - 保持 alpha 通道不变

2. gaussian_blur(input: &[u8], width: u32, height: u32, radius: u32) -> Vec<u8>
   - 使用可分离高斯核（先水平后垂直，复杂度从 O(r²) 降到 O(2r)）
   - 高斯权重用查表法预计算
   - 边界处理用镜像填充

3. sobel_edge(input: &[u8], width: u32, height: u32, threshold: u8) -> Vec<u8>
   - Sobel 3x3 算子检测边缘
   - 超过阈值的像素设为白色，否则黑色

4. adjust_brightness(input: &[u8], width: u32, height: u32, factor: f32) -> Vec<u8>
   - factor > 1.0 变亮，< 1.0 变暗
   - 使用 saturating_mul 和 saturating_add 防止溢出

注意：所有函数接收和返回原始 RGBA 字节数组，不使用 web-sys 类型。
```

Claude Code会生成完整实现。以下是灰度化和高斯模糊的核心代码：

```rust
/// 灰度化：BT.601 加权标准
#[wasm_bindgen]
pub fn grayscale(input: &[u8], width: u32, height: u32) -> Vec<u8> {
    let pixels = bytes_to_pixels(input);
    let output: Vec<Pixel> = pixels
        .iter()
        .map(|p| {
            let gray = (p.r as f32 * 0.299
                + p.g as f32 * 0.587
                + p.b as f32 * 0.114) as u8;
            Pixel { r: gray, g: gray, b: gray, a: p.a }
        })
        .collect();
    pixels_to_bytes(&output)
}

/// 可分离高斯模糊
#[wasm_bindgen]
pub fn gaussian_blur(input: &[u8], width: u32, height: u32, radius: u32) -> Vec<u8> {
    let pixels = bytes_to_pixels(input);
    let w = width as usize;
    let h = height as usize;
    let r = radius as usize;

    // 预计算高斯权重
    let sigma = radius as f32 / 3.0;
    let kernel_size = 2 * r + 1;
    let weights: Vec<f32> = (0..kernel_size)
        .map(|i| {
            let x = (i as isize - r as isize) as f32;
            (-x * x / (2.0 * sigma * sigma)).exp()
        })
        .collect();
    let weight_sum: f32 = weights.iter().sum();

    // 水平遍历
    let horizontal: Vec<Pixel> = (0..h)
        .flat_map(|y| {
            (0..w).map(move |x| {
                let (mut rr, mut gg, mut bb) = (0.0f32, 0.0f32, 0.0f32);
                for (k, &wt) in weights.iter().enumerate() {
                    let nx = (x as isize + k as isize - r as isize)
                        .clamp(0, w as isize - 1) as usize;
                    let idx = y * w + nx;
                    rr += pixels[idx].r as f32 * wt;
                    gg += pixels[idx].g as f32 * wt;
                    bb += pixels[idx].b as f32 * wt;
                }
                Pixel {
                    r: (rr / weight_sum) as u8,
                    g: (gg / weight_sum) as u8,
                    b: (bb / weight_sum) as u8,
                    a: pixels[y * w + x].a,
                }
            })
        })
        .collect();

    // 垂直遍历
    let result: Vec<Pixel> = (0..h)
        .flat_map(|y| {
            (0..w).map(move |x| {
                let (mut rr, mut gg, mut bb) = (0.0f32, 0.0f32, 0.0f32);
                for (k, &wt) in weights.iter().enumerate() {
                    let ny = (y as isize + k as isize - r as isize)
                        .clamp(0, h as isize - 1) as usize;
                    let idx = ny * w + x;
                    rr += horizontal[idx].r as f32 * wt;
                    gg += horizontal[idx].g as f32 * wt;
                    bb += horizontal[idx].b as f32 * wt;
                }
                Pixel {
                    r: (rr / weight_sum) as u8,
                    g: (gg / weight_sum) as u8,
                    b: (bb / weight_sum) as u8,
                    a: horizontal[y * w + x].a,
                }
            })
        })
        .collect();

    pixels_to_bytes(&result)
}
```

**预期结果**：四个完整的图像处理函数，每个都通过 `#[wasm_bindgen]` 标注可导出。

**常见问题**：
- **大图处理时栈溢出**：如果图像很大（>4000x4000），避免在栈上分配大数组。使用 `Vec::with_capacity` 在堆上分配。
- **性能不够理想**：Claude Code能帮你用 `unsafe` 块和指针操作替代安全的索引访问，在关键路径上提速30%以上。

---

## 第三步：构建WASM并验证

```bash
wasm-pack build --target web --out-dir pkg
```

**预期输出**：

```
[INFO]: 🎯  Checking for the Wasm target...
[INFO]: 🌀  Compiling to Wasm...
[INFO]: ⬇️  Installing wasm-bindgen...
[INFO]: Optimizing wasm binaries with `wasm-opt`...
[INFO]: ✨   Done in 3.2s
[INFO]: 📦   Your wasm pkg is ready to publish at ./pkg.
```

检查输出文件：

```bash
ls -lh pkg/
# wasm_image_lab.d.ts     - TypeScript 类型声明
# wasm_image_lab.js       - JS 胶水代码
# wasm_image_lab_bg.wasm  - 编译后的 WASM 二进制
# wasm_image_lab_bg.wasm.d.ts
# package.json
```

**体积优化**：如果 `.wasm` 文件超过 100KB，在Claude Code中输入：

```
当前 WASM 文件体积偏大，请帮我：
1. 检查 Cargo.toml 的 [profile.release] 配置
2. 添加 wee_alloc 作为全局分配器替代系统默认
3. 在需要时使用 wasm-opt 进一步压缩
```

Claude Code会建议使用 `wee_alloc` 并配置 `opt-level = "z"` + `lto = true`，通常能将体积压缩到原来的40%。

---

## 第四步：前端集成

在Claude Code中创建前端文件：

```
请在 www/ 目录下创建前端页面，包含：
1. index.html - 图片上传、滤镜选择、Canvas 展示
2. app.js - 加载 WASM 模块、读取图片到 Canvas、调用滤镜函数
3. style.css - 现代深色主题样式

功能要求：
- 支持拖拽上传图片
- 四个滤镜按钮：灰度化、高斯模糊(r=3)、边缘检测(threshold=50)、亮度调节(slider控制)
- 处理前后对比显示（原图 + 处理后）
- 显示处理耗时（毫秒）
- 处理过程中显示 loading 状态
```

Claude Code会生成完整的三个文件。核心的 `app.js` 逻辑如下：

```javascript
import init, {
    grayscale,
    gaussian_blur,
    sobel_edge,
    adjust_brightness
} from '../pkg/wasm_image_lab.js';

let wasm = null;

async function loadWasm() {
    wasm = await init();
    document.getElementById('status').textContent = 'WASM 模块加载完成';
}

// 从 Canvas 获取像素数据
function getCanvasPixels(canvas) {
    const ctx = canvas.getContext('2d');
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    return new Uint8Array(imageData.data.buffer);
}

// 将处理结果写回 Canvas
function putPixelsToCanvas(canvas, pixels, width, height) {
    const ctx = canvas.getContext('2d');
    const imageData = new ImageData(
        new Uint8ClampedArray(pixels), width, height
    );
    ctx.putImageData(imageData, 0, 0);
}

// 通用滤镜处理函数
function applyFilter(filterFn, ...args) {
    const srcCanvas = document.getElementById('source');
    const dstCanvas = document.getElementById('result');
    const pixels = getCanvasPixels(srcCanvas);

    const t0 = performance.now();
    const result = filterFn(pixels, srcCanvas.width, srcCanvas.height, ...args);
    const elapsed = performance.now() - t0;

    putPixelsToCanvas(dstCanvas, result, srcCanvas.width, srcCanvas.height);
    document.getElementById('timer').textContent = `${elapsed.toFixed(2)} ms`;
}

// 绑定按钮事件
document.getElementById('btn-gray').addEventListener('click', () => {
    applyFilter(grayscale);
});

document.getElementById('btn-blur').addEventListener('click', () => {
    applyFilter(gaussian_blur, 3); // radius = 3
});

document.getElementById('btn-edge').addEventListener('click', () => {
    applyFilter(sobel_edge, 50); // threshold = 50
});

document.getElementById('btn-brightness').addEventListener('input', (e) => {
    const factor = parseFloat(e.target.value);
    applyFilter(adjust_brightness, factor);
});

loadWasm();
```

### Web Worker版本（避免UI冻结）

对于大图片，图像处理会阻塞主线程。Claude Code可以帮你改造为Web Worker架构：

```
请将图像处理逻辑改为 Web Worker 方案：
1. 创建 www/worker.js 作为 Worker 线程
2. Worker 内部加载并初始化 WASM 模块
3. 主线程通过 postMessage 发送像素数据和处理类型
4. Worker 处理完毕后 postMessage 回传结果
5. 使用 Transferable Objects (ArrayBuffer transfer) 避免数据拷贝
```

Worker架构的关键代码：

```javascript
// worker.js
import init, { grayscale, gaussian_blur, sobel_edge, adjust_brightness } 
    from '../pkg/wasm_image_lab.js';

let ready = false;

init().then(() => { ready = true; });

self.onmessage = function(e) {
    const { pixels, width, height, filter, params, id } = e.data;
    
    if (!ready) {
        self.postMessage({ error: 'WASM not ready', id });
        return;
    }

    const t0 = performance.now();
    let result;
    
    switch(filter) {
        case 'grayscale':
            result = grayscale(pixels, width, height);
            break;
        case 'blur':
            result = gaussian_blur(pixels, width, height, params.radius);
            break;
        case 'edge':
            result = sobel_edge(pixels, width, height, params.threshold);
            break;
        case 'brightness':
            result = adjust_brightness(pixels, width, height, params.factor);
            break;
    }
    
    const elapsed = performance.now() - t0;
    
    // 使用 Transferable 零拷贝传输
    self.postMessage(
        { result: result.buffer, elapsed, id }, 
        [result.buffer]
    );
};
```

```javascript
// 主线程调用
const worker = new Worker('./worker.js', { type: 'module' });

function applyFilterAsync(filter, params = {}) {
    const srcCanvas = document.getElementById('source');
    const pixels = getCanvasPixels(srcCanvas);
    const id = Date.now();

    worker.postMessage({
        pixels,
        width: srcCanvas.width,
        height: srcCanvas.height,
        filter,
        params,
        id
    });
}

worker.onmessage = function(e) {
    const { result, elapsed, id } = e.data;
    const dstCanvas = document.getElementById('result');
    const pixels = new Uint8Array(result);
    putPixelsToCanvas(dstCanvas, pixels, dstCanvas.width, dstCanvas.height);
    document.getElementById('timer').textContent = `${elapsed.toFixed(2)} ms`;
};
```

```mermaid
sequenceDiagram
    participant User as 用户操作
    participant Main as 主线程(UI)
    participant Worker as Web Worker
    participant WASM as WASM模块

    User->>Main: 选择滤镜
    Main->>Main: getImageData()
    Main->>Worker: postMessage({pixels, filter})
    Note over Main,Worker: Transferable ArrayBuffer<br/>零拷贝传输
    Worker->>WASM: grayscale(pixels, w, h)
    WASM-->>Worker: Vec<u8>结果
    Worker-->>Main: postMessage({result})
    Note over Worker,Main: Transferable ArrayBuffer<br/>零拷贝回传
    Main->>Main: putImageData()
    Main->>User: 显示结果+耗时
```

---

## 第五步：性能基准测试

在Claude Code中输入：

```
请帮我创建一个性能基准测试页面 www/benchmark.html：
1. 同时用纯 JavaScript 和 WASM 分别执行四个滤镜
2. 在同一张测试图片上运行 10 次取平均值
3. 用柱状图对比显示 WASM vs JS 的处理时间
4. 显示加速倍数（speedup ratio）

JavaScript 参考实现也要包含：灰度化、高斯模糊、边缘检测、亮度调节。
确保算法逻辑与 Rust 版本一致，以便公平对比。
```

预期性能对比结果（1920x1080测试图片）：

| 滤镜 | JavaScript | WASM (Rust) | 加速比 |
|------|-----------|-------------|-------|
| 灰度化 | 12.4 ms | 1.8 ms | **6.9x** |
| 高斯模糊(r=5) | 186.3 ms | 22.7 ms | **8.2x** |
| Sobel边缘检测 | 28.1 ms | 3.2 ms | **8.8x** |
| 亮度调节 | 9.7 ms | 1.5 ms | **6.5x** |

> 数据来源：基于 wasm-image 项目的基准测试方法，在 Chrome 126 / M2 MacBook Air 上运行。

**Claude Code调优技巧**：如果基准测试结果不够理想，可以要求Claude Code进行以下优化：

```
当前高斯模糊性能是 JS 的 4x，不够理想。请分析并优化：
1. 使用 unsafe 块和裸指针替代安全的 Vec 索引
2. 考虑 SIMD 指令加速（wasm-simd feature）
3. 使用 lookup table 预计算权重
4. 确保内存访问是连续的（cache-friendly）
```

开启 WASM SIMD 后，高斯模糊可进一步提速 2-3x：

```toml
# Cargo.toml 启用 SIMD
[target.'cfg(target_arch = "wasm32")'.dependencies]

# 构建时启用 SIMD
# RUSTFLAGS="-C target-feature=+simd128" wasm-pack build --target web
```

---

## 第六步：生产部署

### 方案A：Vercel部署

在Claude Code中：

```
请帮我配置 Vercel 部署：
1. 创建 vercel.json 配置静态站点
2. 设置构建命令为先运行 wasm-pack build，然后复制 pkg/ 到 www/
3. 输出目录为 www/
4. 正确设置 .wasm 文件的 Content-Type: application/wasm
```

Claude Code生成 `vercel.json`：

```json
{
  "buildCommand": "wasm-pack build --target web --out-dir pkg && cp -r pkg www/pkg",
  "outputDirectory": "www",
  "headers": [
    {
      "source": "/pkg/(.*)\\.wasm",
      "headers": [
        { "key": "Content-Type", "value": "application/wasm" },
        { "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
      ]
    }
  ]
}
```

### 方案B：Cloudflare Pages部署

```json
{
  "buildCommand": "wasm-pack build --target web --out-dir pkg && cp -r pkg www/pkg",
  "outputDirectory": "www"
}
```

### 方案C：纯静态部署

对于任何静态托管服务，只需两步：

```bash
# 1. 构建
wasm-pack build --target web --out-dir pkg

# 2. 复制到 www 目录并启动服务
cp -r pkg www/ && cd www && python3 -m http.server 8080
```

---

## 完整项目结构

最终的项目目录结构：

```
wasm-image-lab/
├── CLAUDE.md                    # Claude Code 项目配置
├── Cargo.toml                   # Rust 项目配置
├── src/
│   └── lib.rs                   # Rust 核心算法 + WASM 导出
├── pkg/                         # wasm-pack 输出（构建生成）
│   ├── wasm_image_lab.js
│   ├── wasm_image_lab_bg.wasm
│   ├── wasm_image_lab.d.ts
│   └── package.json
├── www/                         # 前端静态文件
│   ├── index.html               # 主页面
│   ├── app.js                   # 主逻辑（可选Worker版）
│   ├── worker.js                # Web Worker（可选）
│   ├── benchmark.html           # 性能基准测试页
│   ├── style.css                # 样式
│   └── pkg/ -> ../pkg           # 构建后复制
├── vercel.json                  # Vercel 部署配置
└── tests/
    └── web.rs                   # wasm-bindgen-test 测试
```

### 单元测试

让Claude Code帮你编写WASM单元测试：

```rust
// tests/web.rs
use wasm_bindgen_test::*;

#[wasm_bindgen_test]
fn test_grayscale() {
    let input = vec![255, 0, 0, 255, 0, 255, 0, 255]; // 红色 + 绿色
    let result = wasm_image_lab::grayscale(&input, 2, 1);
    
    // BT.601: 红 → 0.299*255 ≈ 76, 绿 → 0.587*255 ≈ 150
    assert_eq!(result[0], 76);  // 红像素的灰度值
    assert_eq!(result[4], 150); // 绿像素的灰度值
    assert_eq!(result[3], 255); // alpha 不变
}

#[wasm_bindgen_test]
fn test_brightness_increase() {
    let input = vec![100, 100, 100, 255];
    let result = wasm_image_lab::adjust_brightness(&input, 1, 1, 1.5);
    assert_eq!(result[0], 150); // 100 * 1.5
    assert_eq!(result[3], 255); // alpha 不变
}

#[wasm_bindgen_test]
fn test_brightness_saturate() {
    let input = vec![200, 200, 200, 255];
    let result = wasm_image_lab::adjust_brightness(&input, 1, 1, 2.0);
    assert_eq!(result[0], 255); // 200*2=400 → saturate to 255
}
```

运行测试：

```bash
wasm-pack test --chrome --headless
```

---

## 完整开发工作流

```mermaid
flowchart LR
    A[需求：图像滤镜] --> B[Claude Code<br/>创建CLAUDE.md]
    B --> C[Claude Code<br/>生成Cargo.toml + lib.rs]
    C --> D[Claude Code<br/>实现算法]
    D --> E[wasm-pack build]
    E --> F{编译成功?}
    F -->|失败| G[Claude Code<br/>修复错误]
    G --> E
    F -->|成功| H[Claude Code<br/>生成前端页面]
    H --> I[本地预览测试]
    I --> J{性能达标?}
    J -->|否| K[Claude Code<br/>优化算法/SIMD]
    K --> E
    J -->|是| L[Claude Code<br/>配置部署]
    L --> M[Vercel/Netlify<br/>发布上线]

    style B fill:#f9f,stroke:#333
    style D fill:#f9f,stroke:#333
    style G fill:#f9f,stroke:#333
    style K fill:#f9f,stroke:#333
```

**Claude Code参与率**：在这个完整项目中，Claude Code承担了约70%的代码编写工作——Rust算法实现、前端页面、部署配置、测试用例全部由Claude Code生成。开发者主要负责需求描述、架构决策和性能验收。

---

## Claude Code辅助Rust/WASM开发的实战技巧

### 技巧一：利用Rust编译器作为"自动纠错"

Rust的强类型系统是Claude Code最好的朋友。当Claude Code生成的代码有类型错误时，编译器会给出精确的错误定位：

```
运行 cargo check 后有以下编译错误：
[粘贴错误信息]

请修复，注意不要改变函数签名和算法逻辑。
```

这种方式比让Claude Code凭空写出完美代码更高效——编译器做了最精确的code review。

### 技巧二：分步复杂度控制

不要一次性要求Claude Code生成所有四个滤镜。分步提交，每步验证：

```
第一步：先只实现 grayscale 函数，写完后我运行 wasm-pack build 验证
第二步：基于第一步验证通过的代码，添加 gaussian_blur
第三步：添加 sobel_edge
第四步：添加 adjust_brightness
```

### 技巧三：用 `--gc-sections` 和 `wasm-opt` 二次压缩

在最终发布前运行：

```bash
wasm-opt -Oz -o output.wasm input.wasm
```

或者在Claude Code中：

```
请帮我配置 wasm-pack 的构建流程，在构建后自动运行 wasm-opt -Oz 压缩。
如果系统没有 wasm-opt，给出安装方法。
```

### 技巧四：利用Claude Code的上下文理解进行重构

当你需要添加新的图像处理功能时：

```
基于现有的 gaussian_blur 实现，请添加一个 median_filter 函数：
- 使用 3x3 窗口
- 对窗口内的像素值排序取中位数
- 遵循现有代码风格（Pixel结构体、bytes_to_pixels/pixels_to_bytes）
```

Claude Code能理解项目现有模式和风格，生成一致的代码。

---

## 延伸应用方向

这个项目可以进一步扩展为：

1. **实时摄像头滤镜**：用 `getUserMedia` 获取摄像头流，逐帧用WASM处理
2. **批量图片处理**：添加多文件上传和批量导出
3. **自定义滤镜编辑器**：可视化编辑卷积核矩阵
4. **WASM + WebGL混合**：用WebGL做渲染，WASM做计算
5. **图像分割AI推理**：用WASM运行轻量ONNX模型做语义分割

---

## 参考来源

1. [WebAssembly Implementation with Claude Code — ClaudeCodeLab](https://claudecode-lab.com/en/blog/claude-code-wasm-integration/) — Claude Code辅助WASM开发的完整工作流
2. [How to Use Claude Code for Rust Development: The Complete Workflow — Beam](https://getbeam.dev/blog/claude-code-rust-development.html) — Claude Code + Rust项目最佳实践
3. [wasm-image: High-performance image processing library — GitHub](https://github.com/patrickrosales/wasm-image) — WASM图像处理5-10x性能基准数据来源
4. [Rust WebAssembly Performance: 8-10x Faster (2025 Benchmarks) — ByteIota](https://byteiota.com/rust-webassembly-performance-8-10x-faster-2025-benchmarks/) — WASM vs JS性能对比测试方法
5. [Rust and WebAssembly Book — rustwasm](https://rustwasm.github.io/docs/book/) — 官方Rust/WASM开发指南
6. [Coding Rust with Claude Code and Codex — DEV Community](https://dev.to/tigranbs/coding-rust-with-claude-code-and-codex-2c4j) — Rust强类型系统如何提升AI编码可靠性
7. [MDN: Compiling from Rust to WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly/Guides/Rust_to_Wasm) — MDN官方Rust编译到WASM教程

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
