multiavatar 1.0.0

Multiavatar pure Rust implementation — 移植自 multiavatar.js(Gie Katon),确定性多文化头像生成器,零运行时文件依赖
Documentation

multiavatar (Rust)

license rust-version GitHub

Multiavatar 的纯 Rust 全功能移植(原始 JavaScript:multiavatar.js,作者 Gie Katon)。 基于输入字符串的 SHA-256 哈希派生 12 位随机种子,映射 12 个环境/部件槽位,从内置 12×16×3 主题部件库拼装成确定性头像, 支持 SVG / PNG / JPEG / GIF / favicon(zip) / favicon.ico / PNG data URI 七种输出,内置 LRU 缓存与 SVG 体积优化。

行为基准:multiavatar-java(Java 版,官方 JS 的逐字符等价移植)。 本仓库 20 组奇偶校验样本(ASCII/中文/emoji/强制角色主题)与 Java 版输出逐字符一致(见 tests/parity_snapshot.rs)。


特性 Features

能力 说明
确定性 同输入永远同头像(SHA-256 → 12 位种子 → 部件映射)
多语言 ASCII / CJK / emoji 输入均可
多输出 SVG、PNG(透明)、JPEG(白底)、GIF(部件逐帧淡入动画)、favicon zip、favicon.ico、data URI
体积优化 坐标精度裁剪(近无损,SVG 文本可减 20-40%),可开关
LRU 缓存 同输入重复生成免重复计算(容量 128,键不含尺寸/格式)
零运行时文件 部件库 gzip 嵌入二进制,单库交付
安全 roxmltree 只读解析(无 XXE);tiny-skia 纯 Rust 确定性光栅化

快速上手 Quick Start

cargo add multiavatar
use multiavatar::*;

// SVG 文本
let svg = multiavatar("demon1110");

// PNG 字节(256×256,透明背景)
let png = to_png("demon1110");

// JPEG / GIF / data URI
let jpg = to_jpg("Binx Bond");
let gif = to_gif("Binx Bond");          // 部件逐帧淡入动画
let uri = to_data_uri("Binx Bond");     // data:image/png;base64,...

// favicon 包
let zip = to_favicon_zip("Binx Bond");  // 16/32/48/64/128/256 → avatar-{size}.png
let ico = to_favicon_ico("Binx Bond");  // 单文件 .ico

// 写文件
write_png("Binx Bond", "avatar.png")?;
write_favicon_ico("Binx Bond", "favicon.ico")?;

// 高级选项(Builder)
let options = avatar_options::AvatarOptions::builder()
    .sans_env(true)          // 去掉环境圆
    .part("05")              // 强制初始角色
    .theme("B")              // 强制颜色主题
    .size(512)               // 渲染尺寸
    .optimize_svg(false)     // 关闭体积优化(原始坐标)
    .build();
let avatar = avatar_with("Binx Bond", &options);
let png512 = avatar.png_sized(512);

演示与全量产物:

cargo run --example demo     # 输出到 demo/(10 组 × svg/png/jpg/gif + favicon + preview_grid.png)

API 一览 API Overview

函数 等价 Java API 说明
multiavatar(input) Multiavatar.multiavatar(input) SVG 文本
multiavatar_with(input, sans_env) multiavatar(input, sansEnv) 去掉环境部件
multiavatar_full(input, sans_env, part, theme) multiavatar(input, sansEnv, part, theme) 强制角色/主题
avatar(input) / avatar_with(input, options) Multiavatar.avatar(...) 不可变产物(SVG + 惰性解析缓存)
to_png / to_jpg / to_gif(+_sized) toPng / toJpg / toGif 字节输出
to_image(+_sized) toImage tiny-skia Pixmap(可继续加工)
to_data_uri(+_sized) toDataUri data:image/png;base64,...
to_favicon_zip / to_favicon_ico(+_sized) toFaviconZip / toFaviconIco 多尺寸打包
render(input, format, options) Multiavatar.render(...) 统一策略入口
write_png / write_favicon_zip / write_favicon_ico writePng / ... 写文件
cache_size / clear_cache cacheSize / clearCache LRU 缓存

架构 Architecture

┌────────────────────────────── 门面 Facade (src/lib.rs) ──────────────────────────────┐
│   Multiavatar:multiavatar* / avatar* / to_* / render / write_* / cache_*            │
│   全局 LRU 缓存(lru 128)+ 单例 SvgComposer(OnceLock)                              │
└───────────────┬───────────────────────────────────────┬──────────────────────────────┘
                │ 产物 Avatar(不可变:SVG 文本缓存 +       │ 渲染(策略模式 Strategy)
                │ 惰性解析文档缓存 OnceLock)              ▼
                │                              ┌──────────────────────────────────┐
                │                              │ AvatarRenderer trait              │
                │                              │  ├ SvgRenderer(原文)             │
                │                              │  ├ PngRenderer(PNG 透明)         │
                │                              │  ├ JpgRenderer(JPEG 白底)         │
                │                              │  └ GifRenderer(逐帧淡入动画)      │
                │                              │  Renderers::create(简单工厂)      │
                │                              └──────────────────┬───────────────┘
                ▼                                                 ▼
┌──────────────────────────── SVG 领域层 src/svg ──────────────────────────────┐
│  SvgParser(roxmltree) → SvgDocument(viewBox+shapes) → SvgRasterizer(Pixmap) │
│  SvgShape(枚举:Path/Polygon/Rect/Line;模板方法:先填充后描边)             │
│  PathDataParser(全指令 + F.6 圆弧→三次贝塞尔)                                │
└───────────────────────────────┬─────────────────────────────────────────────┘
                                ▼
┌──────────────────────────── 核心装配层 src/core ─────────────────────────────┐
│  Sha256AvatarIdHasher(策略) → PartNumberMapper → PartKeyResolver          │
│  AvatarSpec(不可变对象,强制 part/theme 统一覆盖)                           │
│  SvgComposer(模板方法:固定部件顺序 env→head→clo→top→eyes→mouth)          │
│  SvgOptimizer(坐标精度裁剪,与官方 JS 逐字符一致)                            │
└───────────────────────────────┬─────────────────────────────────────────────┘
                                ▼
┌──────────────────────────── 数据层 src/data ─────────────────────────────────┐
│  DataTables(单例 OnceLock):multiavatar-data.gz(gzip 内嵌,24939B)        │
│  解析 T|<partKey>|<name>|<colors> / P|<partKey>|<name>|<svg>                 │
└──────────────────────────────────────────────────────────────────────────────┘

设计模式 Design Patterns

模式 位置 说明
门面 Facade src/lib.rs 统一入口,屏蔽内部流水线
不可变对象 Immutable AvatarSpec / Avatar / AvatarOptions 线程安全共享,惰性缓存
模板方法 Template Method SvgComposer(组装顺序)/ SvgShape::paint 固定骨架 + 可换步骤
策略 Strategy AvatarIdHasher / AvatarRenderer 可插拔哈希与渲染算法
简单工厂 Simple Factory Renderers::create 按格式创建渲染器
单例 Singleton DataTables / 门面 SvgComposer OnceLock 惰性初始化
Builder AvatarOptions::builder() 选项构建
组合 Composite SvgShape 枚举(统一绘制协议) 形状统一处理

与官方 JS / Java 的一致性 Fidelity

  • SVG 逐字符一致:哈希、部件编号、拼装顺序、着色占位符替换、体积优化(含 Math.round half-up 语义、负零 -0、前导小数点 token 不匹配、双空格属性格式) 全部对齐;tests/parity_snapshot.rs 固化 4 组 Java 基准锚点,cargo test 即校验。
  • 光栅化:tiny-skia(f32)与 Java 2D / Chrome(f64)存在亚像素级差异(阈值 <0.1%), 属渲染器精度差异,几何结构完全一致。
  • 数据:部件库 multiavatar-data.gz 与 Java 版同源(单一数据源,本仓库复制自 multiavatar-java)。

测试 Tests

cargo test          # 单测 32 + 集成 14 + doc 1 ≈ 47 项
cargo clippy        # 静态检查

覆盖:哈希/映射/舍入/优化器单测;SVG 奇偶锚点;PNG/JPEG/GIF/favicon/ICO/data URI 格式魔数与结构; 空输入;强制角色主题;LRU 缓存键语义(不含 size/format);GIF 首帧可预览(完整头像)。


构建与产物 Build

cargo build --release   # LTO + codegen-units=1 + strip(体积优化)

依赖(允许常用 crate,均纯跨平台):sha2 flate2 roxmltree tiny-skia png jpeg-encoder gif zip base64 regex lru。


许可 License

MIT。原始 Multiavatar 版权归 Gie Katon;本移植与 multiavatar.js 同源(多文化头像数据来自原项目)。