二维码早已渗透进生活的方方面面,从支付到链接跳转几乎无处不在。但你是否想过,这些黑白方块除了功能强大,还能变得更有艺术感?今天分享一个用 Rust 实现的二维码艺术生成器项目,带你看看如何把枯燥的矩阵变成有趣的像素画。
为什么选 Rust
系统编程和内存安全是 Rust 的核心优势,用它来处理图像生成既高效又稳定。项目中主要依赖三个成熟的库:
- qrcode:负责生成二维码数据矩阵
- image:处理图像绘制与保存
- clap:构建命令行参数解析
有了这些基础,我们可以把精力集中在核心逻辑上。
核心实现思路
1. 基础二维码生成
第一步是把 URL 转换成二维码数据。这里不需要复杂的算法,qrcode 库已经帮我们做好了大部分工作。
// 创建二维码实例
let code = QrCode::new(args.url.as_bytes())?;
// 获取颜色矩阵
let modules = code.to_colors();
拿到矩阵后,我们需要遍历每个模块(module),根据它是深色还是浅色来决定在画布上怎么画。
2. 自定义像素样式
为了让二维码不那么单调,我实现了三种常见的像素风格:方形、圆形和圆角矩形。这部分逻辑其实是在像素级别做替换。
match style {
"circle" => draw_circle_mut(img, px, py, pixel_size, color),
"rounded" => draw_rounded_square_mut(img, px, py, pixel_size, color),
_ => {
// 默认方形填充
for dy in 0..pixel_size {
for dx in 0..pixel_size {
let pixel_x = px + dx;
let pixel_y = py + dy;
img.put_pixel(pixel_x, pixel_y, color);
}
}
}
}
注意这里的循环逻辑,如果是圆角或圆形,需要计算边界点,避免画出界或者形状变形。
3. 彩色支持
传统的二维码只有黑白两色,为了个性化,我们允许用户指定颜色方案。对于未预定义的颜色,可以用一个简单的哈希算法生成一致的色彩值。
// 简单的哈希函数生成固定颜色
let mut hash: u32 = 0;
for byte in input.bytes() {
hash = hash.wrapping_mul(31).wrapping_add(byte as u32);
}
// 从哈希值提取 RGB
let r = (hash & 0xFF) as u8;
let g = ((hash >> 8) & 0xFF) as u8;
let b = ((hash >> 16) & 0xFF) as u8;
这样即使输入不同,同一内容生成的颜色也是一致的,方便调试。
4. 彩虹效果
如果想让二维码更炫酷,可以加上彩虹渐变。核心思路是根据坐标计算 HSV 色相,再转成 RGB。
fn get_rainbow_color(x: u32, y: u32, size: u32) -> Rgba<u8> {
let pos = ((x + y) as f32 / (size * 2) as f32) * 255.0;
let hue = pos as u8;
// 此处省略 HSV 到 RGB 的具体转换逻辑
// ...
}
实际运行时要注意色相范围不要溢出,否则颜色会跳变。
使用示例
项目编译好后,通过 cargo run 即可生成不同风格的二维码。
基础黑白版
cargo run -- --url "https://github.com" --output github.png

圆形像素风格
cargo run -- --url "https://github.com" --style circle --output circle_qr.png

彩虹效果
cargo run -- --url "https://github.com" --rainbow --output rainbow_qr.png

组合效果
当然,你也可以把圆形和彩虹结合起来。
cargo run -- --url "https://github.com" --style circle --rainbow --output rainbow_circle_qr.png

设计原则
艺术化不是乱来,得保证能扫出来。有几个关键点要平衡好:
- 对比度:深色和浅色模块之间要有足够反差,否则扫码枪识别困难。
- 清晰度:别用太复杂的纹理,保持图案干净。
- 尺寸:适当放大像素尺寸能让细节更清晰。
- 颜色:避开相近色系,比如深蓝配浅蓝就不行。
总结
这个项目虽然看起来简单,但涵盖了从需求分析、技术选型、实现细节到问题解决的完整流程。通过它,不仅加深了对 Rust 语言的理解,也掌握了二维码的内部结构和图像处理的基础知识。即使是像二维码这样常见的技术,只要肯动脑筋,也能玩出花样。如果你感兴趣,不妨试试自己动手实现一个,或者在此基础上添加更多有趣的功能。


