自动头像:为无头像访客按邮箱生成 DiceBear 头像(14 套 CC0/MIT 风格可选,不落盘) #5

Closed
opened 2026-10-25 10:10:27 +00:00 by laoyang · 0 comments
Owner

现象 / 诉求

WordPress 在用户未注册、未上传头像时,会用 get_avatar() 生成一个「神秘人」占位图(Gravatar 的默认图)。这个默认图非常丑,而且主题当前走 cn.gravatar.com,该域名在国内已超时 —— 结果是评论区右侧一片空白或破图。

希望主题自带「自动生成头像」能力:按访客邮箱生成一张好看的头像,不需要访客注册、不需要外网请求。

需求细节(用户确认)

  1. 只收录可自由使用、可商用的风格,全部列出来让用户自己选(单选)。
  2. 不落盘。生成后直接用,不做文件缓存、不需要清理机制。
  3. 后台「主题设置」里新增「自动头像」面板:
    • 最上面一个复选框(总开关)。
    • 勾上之后,下面才出现风格列表,让用户选一套并保存。
  4. 判重靠邮箱:同一邮箱永远得到同一张脸,不同邮箱得到不同的脸。

技术方案(已调研完毕,结论确定)

用 DiceBear 的算法与素材,编译成纯 PHP 模板,零外网依赖。

  • DiceBear 9.x 的 PRNG 是 xorshift + 自定义 hashSeed,已用纯 PHP 完整复刻。
  • 渲染顺序严格按 @dicebear/core 的 createAvatar():onPreCreate → getComponents → getColors → onPostCreate → 背景层 → clip mask。
  • 已验证:23 / 31 套风格逐字节一致(186 个用例),单次渲染 0.09~0.15 ms(对比官方 HTTP API 1.5~2.0 秒)。

只收录许可干净的 14 套(CC0 1.0 + MIT),其余 CC BY 4.0 需要署名,不适合随主题分发:

# 风格 许可证 体积
1 lorelei CC0 1.0 132 KB
2 open-peeps CC0 1.0 257 KB
3 notionists CC0 1.0 368 KB
4 notionists-neutral CC0 1.0 47 KB
5 lorelei-neutral CC0 1.0 34 KB
6 pixel-art CC0 1.0 27 KB
7 pixel-art-neutral CC0 1.0 10 KB
8 thumbs CC0 1.0 12 KB
9 shapes CC0 1.0 4.4 KB
10 glass CC0 1.0 5.8 KB
11 rings CC0 1.0 4.6 KB
12 identicon CC0 1.0 4.0 KB
13 initials CC0 1.0 1.1 KB
14 icons MIT 98 KB

合计约 960 KB。按需加载:只 require 用户选中的那一套,其余不解析。

关键坑(已实测):DiceBear 默认调色板基本全是单值(hairColor/eyesColor/mouthColor 都是 000000,skinColor 是 ffffff),不换调色板的话 30 个头像只有 2 种配色 —— 这才是「现在生成的特别丑」的真正原因,光换风格解决不了。所以必须内置人类调色板。

验收标准

  1. 后台「主题设置」出现「自动头像」面板;未勾选时风格列表不显示(或禁用);勾选后出现 14 套风格 + 实时预览。
  2. 选了风格并保存后,未登录访客的评论头像变成生成的头像。
  3. 同一邮箱在多次请求、多次刷新下始终得到同一张头像(确定性)。
  4. 不同邮箱得到不同的头像。
  5. 零外网请求:不访问 gravatar 任何域名、不访问 dicebear 任何域名。
  6. 纯 PHP,不依赖 Imagick / 不依赖 Node / 不依赖 exec。
  7. Requires PHP: 7.0 基线不能被打破(不能用 PHP 8 语法)。
  8. 关闭该功能后,行为回到原来的 get_avatar()。
  9. 已上传真实头像的用户不受影响(只替换「默认图」这一种情况)。
  10. 静态守卫 + 反向验证(falsify)双通过;本地渲染与官方 DiceBear 输出逐字节比对。

涉及范围(预估)

  • inc/theme-core.php:get_avatar 过滤器接入点。
  • inc/theme-options.php:新增选项定义。
  • 新增 inc/theme-avatar.php:PRNG + 渲染器 + get_avatar 钩子。
  • 新增 inc/avatar-styles/*.php:14 套编译后的模板数据。
  • functions.php:require 新文件(按需)。

备注

  • 版本号从 3.2.35 → 3.2.36。
  • 发布仍走 /theme-update/ 通道(zip + readme + update.json),不覆盖服务器主题目录,用户在 WP 后台自己升级。
## 现象 / 诉求 WordPress 在用户未注册、未上传头像时,会用 `get_avatar()` 生成一个「神秘人」占位图(Gravatar 的默认图)。这个默认图非常丑,而且主题当前走 `cn.gravatar.com`,该域名在国内已超时 —— 结果是**评论区右侧一片空白或破图**。 希望主题自带「自动生成头像」能力:按访客邮箱生成一张好看的头像,不需要访客注册、不需要外网请求。 ## 需求细节(用户确认) 1. **只收录可自由使用、可商用的风格**,全部列出来让用户自己选(单选)。 2. **不落盘**。生成后直接用,不做文件缓存、不需要清理机制。 3. 后台「主题设置」里新增「自动头像」面板: - 最上面一个复选框(总开关)。 - 勾上之后,下面才出现风格列表,让用户选一套并保存。 4. 判重靠邮箱:同一邮箱永远得到同一张脸,不同邮箱得到不同的脸。 ## 技术方案(已调研完毕,结论确定) **用 DiceBear 的算法与素材,编译成纯 PHP 模板,零外网依赖。** - DiceBear 9.x 的 PRNG 是 xorshift + 自定义 hashSeed,已用纯 PHP 完整复刻。 - 渲染顺序严格按 `@dicebear/core` 的 `createAvatar()`:`onPreCreate` → `getComponents` → `getColors` → `onPostCreate` → 背景层 → clip mask。 - 已验证:**23 / 31 套风格逐字节一致**(186 个用例),单次渲染 **0.09~0.15 ms**(对比官方 HTTP API 1.5~2.0 秒)。 **只收录许可干净的 14 套**(CC0 1.0 + MIT),其余 CC BY 4.0 需要署名,不适合随主题分发: | # | 风格 | 许可证 | 体积 | |---|---|---|---| | 1 | `lorelei` | CC0 1.0 | 132 KB | | 2 | `open-peeps` | CC0 1.0 | 257 KB | | 3 | `notionists` | CC0 1.0 | 368 KB | | 4 | `notionists-neutral` | CC0 1.0 | 47 KB | | 5 | `lorelei-neutral` | CC0 1.0 | 34 KB | | 6 | `pixel-art` | CC0 1.0 | 27 KB | | 7 | `pixel-art-neutral` | CC0 1.0 | 10 KB | | 8 | `thumbs` | CC0 1.0 | 12 KB | | 9 | `shapes` | CC0 1.0 | 4.4 KB | | 10 | `glass` | CC0 1.0 | 5.8 KB | | 11 | `rings` | CC0 1.0 | 4.6 KB | | 12 | `identicon` | CC0 1.0 | 4.0 KB | | 13 | `initials` | CC0 1.0 | 1.1 KB | | 14 | `icons` | MIT | 98 KB | 合计约 **960 KB**。按需加载:只 `require` 用户选中的那一套,其余不解析。 **关键坑(已实测)**:DiceBear 默认调色板基本全是单值(`hairColor`/`eyesColor`/`mouthColor` 都是 `000000`,`skinColor` 是 `ffffff`),**不换调色板的话 30 个头像只有 2 种配色** —— 这才是「现在生成的特别丑」的真正原因,光换风格解决不了。所以必须内置人类调色板。 ## 验收标准 1. 后台「主题设置」出现「自动头像」面板;未勾选时风格列表不显示(或禁用);勾选后出现 14 套风格 + 实时预览。 2. 选了风格并保存后,未登录访客的评论头像变成生成的头像。 3. 同一邮箱在多次请求、多次刷新下**始终得到同一张头像**(确定性)。 4. 不同邮箱得到不同的头像。 5. **零外网请求**:不访问 gravatar 任何域名、不访问 dicebear 任何域名。 6. 纯 PHP,不依赖 Imagick / 不依赖 Node / 不依赖 exec。 7. **`Requires PHP: 7.0` 基线不能被打破**(不能用 PHP 8 语法)。 8. 关闭该功能后,行为回到原来的 `get_avatar()`。 9. 已上传真实头像的用户**不受影响**(只替换「默认图」这一种情况)。 10. 静态守卫 + 反向验证(falsify)双通过;本地渲染与官方 DiceBear 输出逐字节比对。 ## 涉及范围(预估) - `inc/theme-core.php`:`get_avatar` 过滤器接入点。 - `inc/theme-options.php`:新增选项定义。 - 新增 `inc/theme-avatar.php`:PRNG + 渲染器 + `get_avatar` 钩子。 - 新增 `inc/avatar-styles/*.php`:14 套编译后的模板数据。 - `functions.php`:`require` 新文件(按需)。 ## 备注 - 版本号从 `3.2.35` → `3.2.36`。 - 发布仍走 `/theme-update/` 通道(zip + readme + update.json),**不覆盖服务器主题目录**,用户在 WP 后台自己升级。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: laoyang/wordpress-kratos-yang#5