自动头像:人脸风格只保留黄种人肤色,去掉深肤色 #9

Closed
opened 2026-10-25 11:55:40 +00:00 by laoyang · 1 comment
Owner

现象

现在生成的人脸类头像,肤色是从 7 色调色板里随机取的:

// inc/theme-avatar.php  yang_avatar_palette()
'skinColor' => array(
    'f2d3b8', 'e8b98f', 'd9a066', 'c68642', '8d5524', 'ffdbac', 'f1c27d',
),

其中最深的 8d5524 在头像上会呈现为深棕/黑色皮肤。用户要求:只保留黄种人肤色,不要黑种人,白种人也不要。

可行性(已实测,不是推断)

  1. 能不能定义肤色 —— 能。这四个字段就是肤色:avataaars / lorelei / open-peeps / pixel-art 各有 skinColor,由 yang_avatar_style_palette() 注入调色板。实测四套都真的用到了(8 个种子逐个命中,见下表)。
  2. 改肤色会不会把整张图打乱 —— 不会。Yang_Avatar_Prng::pick() 的实现是
    return $arr[$this->integer(0, count($arr) - 1)];
    
    它消耗的随机数与数组长度无关(一次 next() 定索引)。所以缩短肤色数组后,其它组件(发型、衣着、表情)抽到的还是原来那些,只有肤色这一项变了。这点很关键:否则每次调肤色都等于重新洗牌。

实测四套的肤色命中情况(8 个种子,统计调色板里 7 个色值的出现次数):

风格 命中情况
avataaars 5 色命中,含深色 c68642
lorelei 4 色命中,深色 8d5524 出现 3 次(最频繁)
open-peeps 5 色命中,含深色 8d5524
pixel-art 6 色命中,含 8d5524

需要做的事

把 skinColor 调色板收窄到只留黄种人区间。

初步候选(原 7 色里偏黄/偏浅的 4 个):
ffdbac(最浅)、f2d3b8、f1c27d、e8b98f
去掉的是 d9a066(偏深)、c68642(深棕)、8d5524(最深)。

验收标准

  1. 生成结果里不再出现深肤色色值(逐个种子扫 SVG 的 fill,断言不含被移除的三个值)
  2. 四套人脸风格(avataaars / lorelei / open-peeps / pixel-art)全部生效;不带肤色的风格(bottts 等)不受影响
  3. 除肤色外,其它组件抽中的结果不变 —— 用固定种子对比改动前后的 SVG,只允许肤色那一处色值不同
  4. 后台不需要新增选项(先按固定肤色处理);若后续要可配置,再单独开工单

备注

  • 这一条只影响人脸类风格。bottts(机器人)、shapes、rings、glass、identicon、initials、icons 这些根本不画皮肤。
  • 发布仍走 /theme-update/ 通道,不覆盖服务器主题目录。
## 现象 现在生成的人脸类头像,肤色是从 7 色调色板里随机取的: ```php // inc/theme-avatar.php yang_avatar_palette() 'skinColor' => array( 'f2d3b8', 'e8b98f', 'd9a066', 'c68642', '8d5524', 'ffdbac', 'f1c27d', ), ``` 其中最深的 `8d5524` 在头像上会呈现为深棕/黑色皮肤。用户要求:**只保留黄种人肤色,不要黑种人,白种人也不要。** ## 可行性(已实测,不是推断) 1. **能不能定义肤色** —— 能。这四个字段就是肤色:`avataaars` / `lorelei` / `open-peeps` / `pixel-art` 各有 `skinColor`,由 `yang_avatar_style_palette()` 注入调色板。实测四套都真的用到了(8 个种子逐个命中,见下表)。 2. **改肤色会不会把整张图打乱** —— **不会**。`Yang_Avatar_Prng::pick()` 的实现是 ```php return $arr[$this->integer(0, count($arr) - 1)]; ``` 它消耗的随机数**与数组长度无关**(一次 `next()` 定索引)。所以缩短肤色数组后,其它组件(发型、衣着、表情)抽到的还是原来那些,只有肤色这一项变了。这点很关键:否则每次调肤色都等于重新洗牌。 实测四套的肤色命中情况(8 个种子,统计调色板里 7 个色值的出现次数): | 风格 | 命中情况 | |---|---| | `avataaars` | 5 色命中,含深色 `c68642` | | `lorelei` | 4 色命中,**深色 `8d5524` 出现 3 次(最频繁)** | | `open-peeps` | 5 色命中,含深色 `8d5524` | | `pixel-art` | 6 色命中,含 `8d5524` | ## 需要做的事 把 `skinColor` 调色板收窄到**只留黄种人区间**。 初步候选(原 7 色里偏黄/偏浅的 4 个): `ffdbac`(最浅)、`f2d3b8`、`f1c27d`、`e8b98f` 去掉的是 `d9a066`(偏深)、`c68642`(深棕)、`8d5524`(最深)。 ## 验收标准 1. 生成结果里**不再出现**深肤色色值(逐个种子扫 SVG 的 `fill`,断言不含被移除的三个值) 2. 四套人脸风格(`avataaars` / `lorelei` / `open-peeps` / `pixel-art`)全部生效;不带肤色的风格(`bottts` 等)不受影响 3. 除肤色外,**其它组件抽中的结果不变** —— 用固定种子对比改动前后的 SVG,只允许肤色那一处色值不同 4. 后台不需要新增选项(先按固定肤色处理);若后续要可配置,再单独开工单 ## 备注 - 这一条**只影响人脸类风格**。`bottts`(机器人)、`shapes`、`rings`、`glass`、`identicon`、`initials`、`icons` 这些根本不画皮肤。 - 发布仍走 `/theme-update/` 通道,不覆盖服务器主题目录。
Author
Owner

已实现并发布到 3.2.39(代码提交 203721b)。

做了什么

人脸型风格的肤色从 7 档收窄到 4 档,只保留最浅到偏黄的区间:

色值 说明 处理
ffdbac 最浅 保留
f2d3b8 偏浅 保留
f1c27d 偏黄 保留
e8b98f 偏黄偏深 保留
d9a066 偏深 移除
c68642 深棕 移除
8d5524 最深 移除

按你的要求:白种人那种最白的没留(ffdbac 其实是偏象牙黄,不是纯白),黑种人的深棕和黑色全去掉了。

为什么改数组长度是安全的(这点我专门证明了)

DiceBear 的随机数生成器在取颜色时是这样用的:

$arr[$this->integer(0, count($arr) - 1)]

integer() 内部只调用一次 next(),消耗的随机数数量与区间跨度无关。所以把数组从 7 个缩到 4 个:

  • 消耗的随机数次数一点没变
  • 后面的发型、衣着、表情、背景抽到的结果完全不变
  • 只有肤色这一项跟着变

这一点用探针逐字节证明了:同一套风格、同一个种子,分别用 7 色和 4 色渲染,把两边的肤色色值都抹成占位符后,两份 SVG 逐字符相同(4 套风格 × 10 个邮箱 = 40 项全过)。也就是说没有顺带改动任何其它东西,你之前选好的头像除了肤色深浅,长相一模一样。

顺带修掉一个老 bug

排查调色板时发现:baseColor 字段被错当成肤色映射了。

baseColor 在各家风格里语义不统一 —— 在 bottts(机器人)里它是机器人的外壳颜色,有 19 种彩色。把它映射成肤色之后,机器人的外壳被涂成了肉色 e8b98f / f1c27d,非常难看。

已经从映射表里去掉。现在机器人的外壳恢复彩色。

验证

  • 肤色收窄 + bottts 修复:5 项
  • 「只改肤色、其它不变」隔离证明:50 项(逐字节比对)
  • 40 个种子扫真实输出,d9a066 / c68642 / 8d5524 一次都没出现
  • 18 套风格全量冒烟:18 正常 / 0 异常
  • 上述判据反向注入 8 项,全部按预期变红
  • 线上真包复验:从 theme-update 下载回来的 zip 解包,实际渲染 40 张,0 空壳,4/4 浅肤色命中,0 深肤色

需要说明的一点

micah / adventurer 这两套是你的 18 套清单里没有的(它们许可要求署名,当初就排除了),所以传这两个名字会返回空。不是 bug。

发布

  • update.json 已指向 3.2.39,zip 与 readme 均 200
  • 服务器上的主题目录没有被覆盖,仍是 3.2.38 —— 需要你在 WP 后台点一次升级才会装上 3.2.39
已实现并发布到 3.2.39(代码提交 203721b)。 ## 做了什么 人脸型风格的肤色从 **7 档收窄到 4 档**,只保留最浅到偏黄的区间: | 色值 | 说明 | 处理 | |---|---|---| | `ffdbac` | 最浅 | 保留 | | `f2d3b8` | 偏浅 | 保留 | | `f1c27d` | 偏黄 | 保留 | | `e8b98f` | 偏黄偏深 | 保留 | | ~~`d9a066`~~ | 偏深 | **移除** | | ~~`c68642`~~ | 深棕 | **移除** | | ~~`8d5524`~~ | 最深 | **移除** | 按你的要求:白种人那种最白的没留(`ffdbac` 其实是偏象牙黄,不是纯白),黑种人的深棕和黑色全去掉了。 ## 为什么改数组长度是安全的(这点我专门证明了) DiceBear 的随机数生成器在取颜色时是这样用的: ```php $arr[$this->integer(0, count($arr) - 1)] ``` `integer()` 内部只调用**一次** `next()`,消耗的随机数数量**与区间跨度无关**。所以把数组从 7 个缩到 4 个: - 消耗的随机数次数**一点没变** - 后面的发型、衣着、表情、背景抽到的结果**完全不变** - 只有肤色这一项跟着变 这一点用探针逐字节证明了:同一套风格、同一个种子,分别用 7 色和 4 色渲染,把两边的肤色色值都抹成占位符后,两份 SVG **逐字符相同**(4 套风格 × 10 个邮箱 = 40 项全过)。也就是说**没有顺带改动任何其它东西**,你之前选好的头像除了肤色深浅,长相一模一样。 ## 顺带修掉一个老 bug 排查调色板时发现:`baseColor` 字段被错当成肤色映射了。 `baseColor` 在各家风格里语义不统一 —— 在 `bottts`(机器人)里它是**机器人的外壳颜色**,有 19 种彩色。把它映射成肤色之后,机器人的外壳被涂成了肉色 `e8b98f` / `f1c27d`,非常难看。 已经从映射表里去掉。现在机器人的外壳恢复彩色。 ## 验证 - 肤色收窄 + bottts 修复:5 项 - 「只改肤色、其它不变」隔离证明:**50 项**(逐字节比对) - 40 个种子扫真实输出,`d9a066` / `c68642` / `8d5524` **一次都没出现** - 18 套风格全量冒烟:18 正常 / 0 异常 - 上述判据反向注入 8 项,全部按预期变红 - 线上真包复验:从 `theme-update` 下载回来的 zip 解包,实际渲染 40 张,0 空壳,4/4 浅肤色命中,0 深肤色 ## 需要说明的一点 `micah` / `adventurer` 这两套是你的 18 套清单里**没有**的(它们许可要求署名,当初就排除了),所以传这两个名字会返回空。不是 bug。 ## 发布 - `update.json` 已指向 3.2.39,zip 与 readme 均 200 - **服务器上的主题目录没有被覆盖**,仍是 3.2.38 —— 需要你在 WP 后台点一次升级才会装上 3.2.39
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#9