下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/org-pjg8fqlr--bitmap-recolor.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @org-pjg8fqlr/bitmap-recolor。位图设计稿的确定性改色与去底色。当需要对 PNG/JPG 设计稿做「换底色 / 换主题色 / 去掉某个色块」,且必须保证文字、书法、Logo、图形零失真时使用;与生成式重绘(会改坏文字)相对。触发词:改颜色、换底色、去掉某个颜色的底、重新配色、设计稿改色、文化墙改色、海报改色、物料改色。
阅读全文 (展开查看完整说明)
概述
位图设计稿确定性改色
何时用
- 需求方要求改设计稿的底色或主题色,但图上文字一个字都不能动
- 手上只有位图(截图 / 导出图),没有源文件
- 绝不要用生成式图像编辑:文字密集的设计稿经 AI 重绘后正文必失真
- 反例(该走生成式):需要改变画面内容、构图、风格,而非仅换色
不做什么(边界声明)
- 不改画面内容、构图、风格,不补画、不生成任何元素 —— 那是生成式图像编辑的领地
- 不做超分辨率,不承诺把 800px 的图变清晰 —— 源图分辨率就是上限
- 不能替代设计源文件:位图改色是"应急可用",交付时必须向需求方索取源文件
- 不做矢量图 / PDF / 视频改色 —— 只处理位图(PNG/JPG/BMP 等栅格格式)
- 不自动判断"哪个色该改" —— 色彩语义判断(这个灰是装饰边还是底板)必须由人确认,脚本只负责执行与核查
铁律
- 先测量,后动手。没看清结构前不改一个像素。
- 改色前后必须给出量化验证:改动像素数、保护元素被改数(应为 0)、目标色残留数。
- 分辨率警告必须主动说:源图尺寸 ÷ 目标输出尺寸 → 折算 DPI。低于 150 DPI 不能上墙/印刷,必须点明本次产出是「确认稿」,并索取源文件。
三步闭环(可执行脚本)
依赖:numpy、Pillow(不依赖 scipy,连通域等能力已内置兜底实现)。
第 1 步 · 结构化测量(改色前必跑)
python scripts/analyze_bitmap.py design.png --refine --json measure.json
python scripts/analyze_bitmap.py design.png --target-mm 3000x1200 # 顺带折算有效 DPI输出四部分:
- 主色统计(占比 / 饱和度 / 是否中性灰)——基准色不要凭肉眼估
- 降采样 ASCII 色彩图(块 6~8px)——看全局分栏结构
- 列 / 行投影游程(
--refine可精修到像素级)——用它切「区域矩形表」,边界两侧仍建议留 5px 余量 - 有效 DPI 换算与警告
第 2 步 · 区域化线性解混改色(底色是平涂色时首选)
# 先标定残差阈值:拒绝率落在 1%–5% 的阈值即为合适值
python scripts/recolor_flat.py design.png --bg 6F7170 --calibrate
# 简单情形:单一底色模型
python scripts/recolor_flat.py in.png out.png --bg 6F7170 --new-bg FDFEFF
# 正规情形:显式区域矩形表(推荐,骨架见 assets/regions_example.json)
python scripts/recolor_flat.py in.png out.png --config regions.json
--diff-preview diff.png --report report.json原理:任何像素都可视为 pixel = (1-t)*底色 + t*前景色。对每个候选前景色解出 t,取残差最小的那个,再用新底色重新合成:
t = np.clip(((pix - bg) @ d) / (d @ d), 0, 1) # d = 前景色 - 底色
pred = bg + t[:, None] * d
res = np.linalg.norm(pix - pred, axis=1)
new = bg_new + t[:, None] * (new_fg - bg_new) # ← 用新底色重混,文字边缘自动正确关键:残差设阈值(res <= 22 左右)。残差大 = 该像素不属于「底色+某前景」模型(例如金红交界、两种非底色元素相接),保留原像素,否则会被强行拉成底色的混合 → 出现粉色描边。
为什么优于掩膜法:抗锯齿边缘、文字笔画、印章挖空全部自动正确,不需要连通域、不需要过渡带传播、不需要 done |= 顺序管理。整图改色 = 一次矩阵运算。
前景色清单必须显式枚举(从测量结果实测取色):底色上压着的每一种颜色都要列进去(红、暗红、白、墨、金……),漏一种就会被相邻最近的前景色吃掉。特别注意:与相邻区域交界产生的混合色也要列进清单(如灰底区里的「白卡」),否则边界像素会被残差阈值拒绝、留下原色灰缝。
区域划分(本方法的必需件):见「坑 · 平涂底色与『白底黑字』在色彩上不可分」。
第 3 步 · 量化自检(交付前必跑)
python scripts/verify_recolor.py orig.png out.png
--target 6F7170:FDFEFF
--protect 1A1A1A --protect B01E24 --json check.json逐项报告:改动像素数与落位、改动横向分布(查泄漏)、目标色转换率、保护元素核心像素被改数(应为 0)。
判据说明:保护色判定分核心像素(色距≤6,必须零改动)与边缘像素(宽匹配内)。底色一变,边缘像素按物理必然跟着重混(灰底黑字 t=0.8 的边 → 白底黑字同 t 的边),不算违规,仅列出供人工核对;只有当边缘大幅变动超过宽匹配的一半时才判「大面积重绘」。
流程(无脚本场景 / 需要手工介入时)
1. 先判断「要改的色」承担什么功能 ← 最容易翻车的一步
同一个灰色可能是三种完全不同的东西:
| 角色 | 换色后果 |
|---|---|
| 装饰边 | 直接换,安全 |
| 底板 / 墙板色 | 压在其上的元素会消失或失读(红字压红底 = 消失) |
| 分隔色 | 换浅色会让相邻区块糊成一片 |
先回答「这个色块上面压着什么」,再决定新色,并把代价明确告诉用户。
2. 软权重替换(底色不是平涂色、或只有单一色相时用)
wA = np.clip((TOL_HI - d) / (TOL_HI - TOL_LO), 0, 1)
wA[(b - r) < 4] = 0 # ← 关键:排除中性灰,保护黑字抗锯齿边
out = out * (1 - wA[..., None]) + newcolor * wA[..., None]- 硬阈值替换会产生锯齿硬边;软权重让过渡像素按比例混合,边缘自然
- 必须加色相/饱和度条件,否则正文黑字的边缘灰度会被一起吞掉
3. 邻域补齐
hole = (d < TOL) & (neutral) & (other_w < 0.25) & dilate(mainA > 0.7, 2)
mainA[hole] = 1.0无 scipy 时 dilate 自实现:
def dilate(m, k):
p = np.pad(m, k, mode='edge')
out = np.zeros_like(m)
for dy in range(2*k+1):
for dx in range(2*k+1):
out |= p[dy:dy+H, dx:dx+W]
return out4. 区域限定
只有局部需要特殊处理时(侧栏文字改金、中央保留红),用 x/y 掩膜限定。动手前先校验边界带内无目标元素:打印该带的权重和,为 0 才安全。
5. 连通域分流(改「文字」或换「底」时的必需步骤)
当指令是「A 色变 X、B 色变 Y」且 B 色上有压着的文字时,纯色距/软权重不够用——必须先按连通域把元素分成「块面」和「文字」,两类目标色不同。
必做:闭运算连断。 密集文字会把底色的连通域切成碎块,直接按面积筛会把整块底判成「小碎块」。先闭运算再取连通域,最后与原掩膜求交:
base_closed = erode(dilate(BG_MASK, 4), 4) # 先膨胀后腐蚀,桥接文字造成的断裂
CARD = 面积>=1200 的连通域 & BG_MASK红/彩色连通域分流(按优先级判)
| 判据 | 归属 |
|---|---|
area >= 1000 或 bbox 宽/高 >= 95 | 块面(旗、条幅、飘带)→ 保留 |
30<=bbox<=110 且 bbox 四边占比>=0.60 且 内部异色占比>=0.25 | 印章(红框环 + 内部异色底)→ 整块保留 bbox |
其余 → 取 ring = dilate(comp,6) & ~dilate(comp,1),看邻域 | 邻域中「原底色」占比 >= 0.22 → 压在底色上的文字 → 保留;否则 → 压在新底上的文字 → 换色 |
识别印章的关键是 bbox 四条边上的红色占比(闭合红框几乎全是边色),不是面积。用面积阈值会把印章红框和文字笔画混在一起。
印章常是「红框 + 白底 + 红字」的阳文,放大后红占主导,肉眼极易误判成「红底白字」,必须逐行打印色标确认。
异色底上的小文字保护:小连通域且 ring 中主色占比 >= 0.45 → 保持原色(保护印章白字、红线内的白线)。
应用优先级(顺序错会互相覆盖,必须严格遵守)
印章 / 块面 / 块内小文字 > 底色 > 底→新色 / 文字→新色底色掩膜来自闭运算,会覆盖块内小文字,所以要先把小文字落定并 done |=,或用 & ~done 逐级收窄。
6. 过渡带
所有未被任何掩膜命中的像素(抗锯齿边缘)用 8 邻域距离传播(迭代 20 次)填最近目标色,比直接留原色干净:
dist = np.where(done, 0.0, 1e9); acc = target.copy()
for _ in range(20):
if not und.any(): break
# 8 个方向的 pad+位移取 min(dist+1),同步搬运对应目标色预防:过渡带像素数突然变大(正常 <5%)就是有元素类没被显式处理,会整块被吃掉。
坑
- 平涂底色与「白底黑字」在色彩上不可分 ← 解混法唯一的死穴,必读。
墙板灰 #6F7170 与「白卡上的黑字抗锯齿到 77% 覆盖」在 RGB 里几乎同色(两者到 #FDFEFF 的插值都落在同一位置)。若把底色灰像素误判为「卡上墨字」,解混会算出 t≈0.77 → 该像素被压成深色 → 整块墙板变成墨黑;反之把卡上灰阶字体边缘误判为「墙板灰」→ 文字边缘被染成新底色 → 字迹发虚、笔画变细。解法:必须给一张显式的区域矩形表(哪几段 x 是「灰底区」、哪几段是「白底区」),并:
- 卡片矩形内缩 2px:边界混合像素留给「灰底区」处理,灰底模型能自动算对;若划进卡片区会产生一圈暗描边。
- 灰底区不必内缩:落在灰底区里的白卡像素,灰底模型会算出
t≈1,结果仍等于新白/新金,天然正确。 - 分栏规整的设计稿(文化墙、展板)用列投影就能切出区域表,不必做连通域。
- 换一版源图就必须重测,色值和坐标都不能沿用:同一份设计从 945×294 换成 1920×497 的「高清原图」后,墙板灰从冷调
#5B7078变成了中性#6F7170,分栏宽度也重排(160→182px 等)。沿用旧阈值/旧坐标会整片错位。每次拿到新源图,第一步永远是重新测量。 - JPEG 振铃会在强边界产生 1px 暗线:灰底↔白卡交界处会出现比两侧都暗的
#414244–#484848单列像素。它们会被「墨色文字」掩膜命中,误报成「文字被改」。校验墨色保护率时要先把这类边界列排除,或直接承认它们是伪影(换色后反而被抹平,属改善)。 - 换底色的指令隐含「压在底上的文字也要跟着换」:只处理「主色文字」而漏掉其他颜色的文字(如白卡上既有红字又有中性黑字),漏掉的那类会落进过渡带被底色新色吃掉 → 整栏正文蒸发。动手前必须枚举底色上所有文字色(主色统计 + 逐行色标),逐一显式给目标色。
- 「白色换色」是否包括红块里的挖空白字? 机械执行「白→新色」会让印章/红章里的挖空白字一起变色。物理上「挖空」理应透出新底色,视觉上反而更自洽;但这是需要用户拍板的取舍,不能默默改,也不能默默不改——出细节对比图让他选。
- 假阳性残留:自检只按色距会把中性灰(
#6E6E6E)算成「未替换的灰底」。真判据须带(b-r)>=8色相条件,否则白忙一场。(verify_recolor.py已同时输出两个口径。) - 条纹 / 梳齿区:缝和肋是两种颜色,去掉底色后条纹会变成「新底色 + 条纹色」,可能比原来更跳。先出小样确认。
- 区域掩膜边界:边界若切进色块会产生 1~2px 色差竖线。给边界留 5px 余量并校验。
- 新底色不要与现有同色系块面撞色:把白卡改成红
#B01E24时,与同图上的暗红条幅#B60000、旗帜红#E30300会融合成一片。选色前先列出图上所有同色系元素的色值做对比度核算,并把取舍讲给用户。 - 无 scipy:连通域可用行游程 + 并查集,或用列/行投影近似(多数设计稿是规整分栏,投影就够)。
「字迹清晰 / 要审核文字内容」怎么交付
这条要求与源图分辨率直接冲突,必须分两张图交付,不要混在一张里:
- 配色对比图:给需求方选色用(1.5× 放大即可,重点是块面关系)。
- 文字核对图:单独一张、按栏裁切、放大 5×、加保护性锐化,取自原稿而非改色版(原稿对比度最高)。
- 每栏下方标栏名,便于定位。
- 必须量出正文单字实际像素高(行投影找 ink 行 → 相邻 ink 行间距 = 行距,ink 行高 ≈ 字高)并写进图注。
- 单字高 < 8px 时明确告知无法逐字校对:可读出大标题与中等字号文字,小正文只能对着标准文本逐句比对,不能冷读。要求提供设计源文件。
- 不要靠超分/生成式补笔画——正式文本(党建、公告类)一字错就是事故。
交付
- 每个方案单独出图 + 一张与「原稿」并列的对比长图(标注方案名与色值)
- 至少给 3 个配色方向,不要只给一个
- 保留处理脚本与区域表,源文件到手后可复跑
- 附一份给设计方的改色工单:原色值 → 新色值对照表