“叠字母”这个说法第一次听的时候,我以为是某种文字接龙小游戏,直到有人把一张叠得密不透风的字母海报甩到我面前,问我能不能做一套同款,我才意识到它指的是一类视觉手法:把两个以上的字符放在同一块版面上,让它们互相压住、错位、交叠,原本横平竖直、各自为政的字符之间就会挤出全新的形状。你可以把它理解成给自己的名字做一枚私章,两个字母一扣,就成了别人模仿不来的符号;也可以理解成一种纹理生成方式,几十个字母压成一片,远看是肌理,近看才认出是字。这篇文章想聊的就是这件事:叠字母从想法到成品的完整路径,包括骨架怎么定、压叠顺序怎么排、手作和代码两条线分别怎么落地、批量做的时候参数怎么算,以及我在这上面踩过的坑。无论你是想给个人账号做头像、给手工制品做印花,还是纯粹对字形改造有兴趣的初学者,都能从里面挑到能直接抄走的部分。
1. 叠字母到底在做什么:三种诉求与三条技术路线
先把这个词拆开看。叠字母的核心动作只有两个:字符的选择,和字符之间的空间关系处理。听起来简单,但不同人做这件事的目的完全不同,目的不同,做法就天差地别。我接触过的需求大致能归成三类,先把这三类摆清楚,后面选方案的时候才不会走弯路。
1.1 从两个字母的私章到一整墙的字
第一类是标识型,也是最常见的。取两到三个字母,让它们在有限的方框里交叠成一个紧凑的符号。这种做法的历史很久,欧洲的贵族花押、日本的商家印、老式火漆封蜡上的缩写,本质上都是同一套逻辑:有限的字符数、严格的外框、笔画互相借用。这类叠字母的评判标准很明确——缩到很小的尺寸还能认出来,外轮廓要"整",不能长出一堆散落的尖角。
第二类是装饰型。海报、封面、文化衫印花、包装底纹,用几十个甚至上百个字符层叠堆出一片肌理。这类作品的关键词是密度和节奏,单个字母认不认得出来并不重要,重要的是整体的疏密变化和深浅层次。做这类东西最容易翻车的地方,是叠得太均匀,均匀就等于死板,一眼看过去像贴在墙上的壁纸。
第三类是趣味型,偏教育和娱乐。儿童识字卡、拼词游戏、字谜题目,把字母叠在一起让人找出藏在里面的词。这类东西的约束条件反而是最严的:可辨识度必须放在第一位,叠归叠,每个字母的轮廓必须有足够的信息量支撑辨认,笔画不能糊成一团。有的人做这类内容,效果不好往往不是创意问题,是字重和层数没控制住。
搞清楚自己要做哪一类非常重要,因为这三类对"叠多少、压多深、留多白"的要求是互相打架的。标识型要克制,两三个字符、重叠率控制在两三成;装饰型要放开,字符越多越好、允许大面积压死;趣味型要精准,宁可在重叠区域做减淡处理也要保住轮廓。我在最初做的时候就是没分清,拿装饰型的密度去做标识,结果做出来的东西小尺寸一缩就废了。
1.2 手作、矢量、程序生成,三条路各自的边界
确定诉求之后就是选技术路线,主流的三条:
- 手作路线:彩色卡纸、不干胶贴、印章、剪纸、甚至旧书页剪下来的字,手动拼贴后拍照或扫描。
- 矢量路线:在矢量绘图软件里打散字符、转曲、做布尔运算,精确控制每一条路径。
- 程序路线:用代码读取字体文件,批量地渲染、偏移、旋转、混合,一次性产出大量变体。
这三条路不是互斥的,实际项目里通常是组合使用的。我一般把手作当成"探路"环节,因为它反馈最快——剪几个形状往桌上一摆,五分钟就能看出这个组合挤不挤、重心偏不偏,比在软件里调半天数值直观得多。手作的短板也很明显:精度不可控,同一个形状手工剪两次得不到完全一样的结果,要复刻或放大会很痛苦。
矢量路线的优势是可控和可交付。字符转成路径之后,每一条曲线的锚点、每一个交叠区的布尔关系都能精确调整,导出成分层文件交给印刷或制作方也不会出问题。它的成本是学习曲线,路径查找器里那几个运算(并集、减去顶层、交集、排除)背后其实有挺多讲究,初学者最容易在有描边的字符上翻车——描边没转曲就做布尔运算,出来的结果常常缺一块。
程序路线的价值在于"量"。如果你要做的是一个系列,比如二十六套不同字母组合的印花,或者要生成一百张同风格的封面,人工一个一个调是不现实的。代码的好处是把"叠字母"这件事抽象成一组参数:偏移量、旋转角、缩放比、色相、混合模式、层数。参数一变,整批结果就跟着变,而且可以固定随机种子复现。缺点是对审美判断的依赖依然在人身上,代码能保证一致性,保证不了好看。
1.3 我为什么最后选了草图、矢量、代码三段式
踩过几轮之后,我固定下来一套流程,分三段:铅笔草图定骨架,矢量软件做精修,代码负责批量扩展。这个组合的理由很实在。
铅笔草图这一步不是为了好看,是为了低成本试错。拿一张方格纸,先用固定宽度的马克笔把每个字母的笔画统一画一遍——注意,一定要用等宽的笔,可以是平头马克笔也可以是针管笔,别用铅笔轻描淡写,因为你后面要判断的是笔画宽度的比例关系,铅笔那种可粗可细的线条会骗人。画完之后剪下来,在桌上摆,试不同的叠法。这一步十分钟能试十几个方案,比在软件里拖图层快十倍。
矢量精修是把选中的方案"钉死"。草图扫描进去做二值化,再把轮廓描成路径,这一步出来的东西是可编辑、可缩放、可复制的。字符的骨架偏差、笔画粗细的轻微不一致,都在这一步修掉。我一般的做法是先从字体里取出字符作为参考底图,把草图描的路径往上面对齐,这样既保留了手绘的生动感,又借了字体本身的骨架稳定性。
代码批量是在方案定型之后才做的。这个顺序千万别颠倒——先写代码再想设计,很容易陷进参数调优里出不来,生成几百张垃圾,最后还是得回到纸上重新画。代码的正确定位是"把一个已经验证过的方案复制并变化出一批",不是"帮我想到一个好方案"。
2. 先定规则再下笔:叠字母的骨架与秩序
叠字母之所以有时候看起来像乱码、有时候又很耐看,差别几乎全在"秩序"两个字上。字符叠在一起,人眼会自动去寻找规律:哪条线在延续、哪个角度在重复、哪个区域是视觉的落点。这些规律如果存在,读者就觉得"讲究";如果不存在,就是"糊成一团"。所以在动手之前,有几条规则必须先写死。
2.1 统一字重是让叠字母不散的前提
所有的叠字母设计,第一件事都是统一笔画宽度。原因在于,当两个字符交叠,交叠区域会形成一个色块,如果两个字符本身的笔画粗细差距很大,交叠区域跟周围的对比就会失衡,视觉上就会有"一块深一块浅"的破碎感。
具体怎么定?我用一个简单比例来控制:笔画宽度 w 与字高 H 的比值落在 0.10 到 0.14 之间。小于 0.10,笔画太细,叠起来交叠区不明显,看不出"叠"的效果;大于 0.14,笔画太粗,字符的内白(也就是字肚子里那块空白)会被吃掉,缩小后直接糊。这个比例不是绝对的,字符笔画数多的(比如 M、W、E)可以往 0.10 靠,笔画数少的(比如 I、L、O)可以往 0.14 走,这样视觉上会感觉粗细一致,虽然数值上并不相同,这叫视觉补偿,是老排版工的常规操作。
统一字重还有一个副作用是好的:它强迫你简化字形。为了把所有笔画拉到同一宽度,你必须放弃字体原有的那些细微的粗细变化,字符会变得更接近几何图形。这对叠字母来说反而是加分的,因为几何化的形状在交叠时产生的负空间更干净,不会有毛刺和藕断丝连的小尖角。
2.2 谁压谁:提前写死的层级规则
叠字母里最容易被忽略、也最影响成品气质的一件事,是 z 轴顺序。三个字母叠在一起,谁在最上面,一共六种排法,每一种给人的感觉都不一样。初学者常犯的错是随手调,调到最后自己都乱了,画面中间出现一堆互相切割的碎片。
我的做法是提前定一条规则,然后所有作品都照这条规则走。常用的规则有三种:
| 排序依据 | 规则描述 | 适合的场景 |
|---|---|---|
| 笔画数量 | 笔画少的压下笔画多的 | 标识型,主角更突出 |
| 字符顺序 | 按阅读顺序,后面的压前面的 | 装饰型,有方向感 |
| 视觉重量 | 面积大的压面积小的 | 需要重心稳定的构图 |
| 明度 | 深的压浅的 | 需要层次分明的多色方案 |
| 随机固定种子 | 定一个种子,每次生成都一样 | 程序批量,保证可复现 |
我个人偏爱"笔画少的在上"。理由很朴素:笔画少的字符(比如 I、L、T)形状简单,压在上面能保持完整的轮廓,读者一眼就能认出主字;笔画多的字符被压住一部分,即使有遮挡,靠它复杂的结构仍然能被识别。这样主次分明,不会出现"谁都想当主角"的混乱。
有一点必须提醒:规则一旦定了,整批作品就要一致。我见过一些作品,单看每一张都不错,摆在一起就散架,原因就是每张的压叠逻辑都不一样。系列感这个东西,靠的就是这种不容易被察觉的内部一致性。
2.3 交叠区的面积与视觉重心
两个字符重叠部分的面积,是这个设计里最敏感的参数。我用一个粗略的量化方式来控制:交叠面积占单个字符实心面积的 20% 到 35% 之间,视觉效果最舒服。
低于 20%,两个字符基本是"靠着",看不太出叠的意思,浪费了这个手法;高于 35%,重叠区会变成一大块实心色块,字符的辨识度急剧下降,画面上会出现一块没有信息的死区。这个比例是我拿网格纸数格子估出来的,不需要很精确,肉眼判断就够,但你心里得有个数,不然很容易一路叠到失控。
视觉重心是第二个要盯的点。叠字母的重心应该落在画框的中心偏上一点的位置,略微偏高会让人觉得"稳而不沉"。做法是在草图阶段就把画框画出来,摆完之后眯起眼睛看,找最暗的那一块——那是最吸引眼球的地方。如果这块暗区跑到了角上或者贴了边,整个构图就会往那个方向倒,即使字符本身摆得很正,看起来仍然是歪的。修正的办法通常是调整最大那块交叠区的位置,比如把本来压在右下角的两个字符整体上移,或者把重叠深度减一点,让暗块散开。
负空间也归在这一节里说。叠字母最漂亮的地方往往不是黑色的笔画,而是笔画之间被围出来的白色缝隙。好的叠字母,那些白缝应该是形状清晰、大小有变化的;差的叠字母,白缝会碎成一堆大小相近的小洞,看着闹心。判断方法很简单:把图缩小到原来的一半再看,如果白缝还是能分辨出形状,说明负空间是成立的;如果全都糊成一片麻点,说明字符太密或者笔画太粗,得减层或者减重。
2.4 配色:让交叠区产生的第三色是可控的
多色叠字母里,颜色的处理比大多数人想的要复杂一点。因为只要你用了半透明或者叠压混合,两个字符压在一起的地方就会自动产生第三种颜色。这个颜色是"惊喜"还是"惊吓",取决于你选的两个原色之间的关系。
我总结的经验是两条:
- 色相间隔控制在 60 度以内:两个颜色的色相靠得近,混出来的第三色仍然是同一个色系里的,容易和谐。色相差太大(比如蓝和黄),叠出来会是脏兮兮的灰绿,除非你就是要那个脏感。
- 明度差保持在 30 以上:两个颜色的明度拉开,即使叠压混合后,交叠区仍然能分辨出层次,不会黏在一起。
如果做的是单色方案(黑白或者只有一个专色),那就要靠不透明度来区分层级。常见做法是:最上层的字符 100% 不透明,中间层 70%,最下层 45%。这个梯度不能太小,低于 20% 的差值肉眼几乎看不出来,层次就白做了。
还有一个特别容易忽略的坑:屏幕上看的效果和印出来的效果差得很远。屏幕是发光的,浅色叠加会显得通透;纸是吸光的,同样的色值印出来会发闷、发暗。我的一般做法是把叠压区的颜色往亮的方向提 5% 到 8%,或者干脆把叠压混合改成一个固定的专色,用套印的方式来保证可预测。这一点在后面的导出参数里还会再提一次。
3. 手作与矢量:从一张草稿到能交付的文件
这一段讲的是单件作品的完整落地过程。虽然听起来是"手工活",但里面的每一步都有明确的判断标准和参数,不是凭感觉糊出来的。
3.1 草图阶段的四个关键动作
草图画得好不好,直接决定了后面在软件里要花多少时间补救。我固定下来的动作有四个:
第一个动作是画格。在纸上画出一个正方形外框,边长按你要做的实际尺寸等比缩小,比如做 40 厘米的印花,纸上画 10 厘米,比例 1:4。有了这个框,你才能判断字符有没有冲破边界、重心是不是偏了。没有框的草图基本等于废纸,因为你根本不知道自己在什么范围内构图。
第二个动作是定基线和中线。在框内画出水平基线和垂直中线,字符的底部落在基线上,整体围绕中线分布。这一步是为了防止做完之后发现整体偏左或者偏下——人的手在画东西时有天然的偏移倾向,不借助参考线根本察觉不到。
第三个动作是用等宽笔统一笔画。前面提过,必须用固定宽度的笔,把每个字符的笔画都画成同样的粗细。这个动作会逼着你做简化,比如把 S 的两头改成平切,把 A 的横杠拉到跟竖笔一样宽。这些简化正是叠字母需要的东西。
第四个动作是剪开摆位。把画好的字符剪下来,在画框里反复摆。摆的过程要注意看三件事:交叠区的位置是否落在视觉重心上、负空间有没有出现重复的小洞、整体轮廓是不是"整"。判断方法还是眯眼看和缩小看,这两个动作能帮你过滤掉大部分坏方案。
我要强调一点:草图阶段就应该用到最终尺寸的等比比例,不要在很小的纸上画完再放大,因为线条的相对粗细在小图和大图上给人的感受是不一样的。一个在小图上看着舒服的比例,放大四倍之后笔画会显得偏细。宁可画大一点。
3.2 扫描、二值化与路径简化
草图过了扫描这一步,就有了可以进软件的数字文件。这里有三个参数值得说清楚。
扫描分辨率。黑白稿我一般用 600 dpi,彩色稿 300 dpi 就够。为什么黑白稿要这么高?因为后面要做二值化,边缘的抗锯齿像素会成为描边时的噪声,分辨率越高,边缘过渡的像素带越窄,二值化之后轮廓越干净。用 300 dpi 扫一个 10 厘米的稿子,得到的图是 1181 像素,边缘噪点占的比例相当可观。
二值化的阈值。不要用自动阈值,自动阈值对不均匀光照的纸面很不友好,左边干净右边脏。手动调,把阈值定在铅笔灰和纸白之间,通常是 40% 到 50% 的灰度位置,或者干脆用色阶把黑白点往里收一点,让边缘的灰过渡消失。出来的图应该是纯黑的形状配纯白的底,中间没有灰。
路径简化的容差。这一步是描轮廓之后的收尾,容差太大会把有用的曲线细节抹掉,太小则路径节点爆炸,一个字母可能上千个节点,编辑起来卡顿、导出文件也大。我的经验值是:容差设成字符高度的 0.3% 到 0.5%。比如一个高度 600 像素的字符,容差设在 1.8 到 3 像素之间。节点数量控制在每个字符 80 到 150 个之间,既有弧度又有可编辑性。
描完的路径要检查两件事:一是路径是否闭合,不闭合的路径在做布尔运算时会出问题;二是自交,就是路径自己跟自己交叉,这种在布尔运算里常常会生成反向的填充区。发现自交就手动删节点或者用简化工具再过一遍。
3.3 布尔运算之后必须做的碎片清理
字符叠在一起之后,为了让成品是一块完整的形状(而不是一堆叠着的图层),通常要做布尔运算合并。这一步是最容易出问题的环节,主要表现是:合并完了之后,交叠区旁边出现一堆孤立的小碎片,或者原本该保留的区域被减掉了。
碎片产生的原因,多半是两个路径的边缘没有真正相交,而是有一个极小的错位——可能是 0.1 毫米的偏差,你放大到 800% 才看得见,但在布尔运算里,这个缝会变成一条孤立的小岛。解决办法不是一遍遍重做,而是在合并之前先做一次"路径描边"操作,给所有路径加一个 0.05 到 0.1 毫米的描边并转成填充,把这种微小的缝隙封死,然后再做并集。
另一种情况是"减去顶层"用错了。很多人想让下层从上层中间露出来,就用减去,结果得到的是一个带缺口的形状,而如果有三个以上的字符,这个缺口会把本该连着的部分切断。这时候应该用"排除重叠",它会保留所有区域、但把交叠区挖空,效果是交叠区变成透明。这两种运算的视觉结果是完全相反的,不要在同一个作品里混用。
合并完成后一定要做的收尾动作:全选加轮廓化、清理游离锚点、检查路径方向。路径方向不对的表现为填充反了——本实心的地方变成空心。这个在导出成矢量文件之后会暴露出来。
3.4 导出参数怎么算,别拍脑袋
交付的时候,参数是必须算的,不是"随便导个大的"。给你两个常用的算式。
位图导出:需要的像素 = 成品物理尺寸(英寸)× 目标分辨率(dpi)。做一张 30 厘米见方、300 dpi 的印花图,30 厘米是 11.81 英寸,算下来约 3543 像素,稳妥起见导 3600 或 4000 像素。如果做的是大幅面的喷绘,观看距离在 2 米开外,分辨率 100 dpi 就足够,30 厘米的图只需要 1181 像素,但你不会按 30 厘米做,通常是按 2 米算,那就是 7874 像素。
矢量导出:SVG 是好选择,但要注意两点。一是描边必须转曲,没转曲的描边在别的软件打开时可能被忽略或者显示成默认宽度,你的作品立刻就变样了。二是文字必须转成路径,否则对方电脑上没有那个字体,打开就是一堆错误的替代字形。这两件事在导出前要单独检查一次,别指望能记住。
另外,如果成品要去印刷,颜色模式要提前切成 CMYK,别在 RGB 下做完再转——转换过程会让鲜艳的颜色掉一大截,尤其是那些饱和的橙和绿。我的做法是做完造型之后另存一个副本专门转 CMYK,然后在 CMYK 下再调一次颜色,接受它"发闷"的现实,在允许范围内把对比拉回来。
4. 用代码批量做叠字母:一套可复现的流水线
单件做完,如果要批量出系列,就该让代码上场了。这一节讲的是怎么把"叠字母"变成几组可以调的参数,以及怎么用最少的依赖把它跑起来。
4.1 环境准备与依赖选择
我的环境很简单:Python 3.10 以上,一个图像处理库就够。如果你想用矢量输出,也可以直接拼 SVG 字符串,不需要额外的库,但需要自己处理路径数据,稍微麻烦一点;位图路线发展快、调试直观,适合绝大多数需求。
python -m venv stack-env source stack-env/bin/activate pip install pillow这段没什么花哨的,虚拟环境是必须的,因为图像库的版本差异有时候会影响渲染的边缘处理,不同版本跑出来的东西不一样,你会误以为是参数问题。
字体这块要提一句:用可商用的开源字重字体。叠字母做完之后往往会用在商品、封面、印花上,字体的授权情况要提前搞清楚,尤其是那些标注"仅限个人使用"的字体,一旦商用会有麻烦。开源字体里选一个字重够粗的(黑体、粗圆都行),因为叠字母需要粗笔画,细字体的笔画太窄,叠起来没有分量。另外,同系列里要挑粗细一致的那一档,不要东拼西凑。
4.2 参数模型:偏移、旋转、缩放、色相
这套流程的核心是把一张图拆成几个可调的旋钮。我用的参数是这几个:
| 参数 | 含义 | 建议范围 | 取值逻辑 |
|---|---|---|---|
| jitter | 单个字符的位置抖动幅度 | 字号的 0.15 到 0.25 倍 | 太小看不出叠,太大散架 |
| rotate | 旋转角度 | ±12 度 | 超过这个角度字符会"飞出去" |
| scale | 单字符缩放 | 0.9 到 1.1 倍 | 制造轻微的错落感 |
| alpha | 图层不透明度 | 0.45 到 1.0 | 按下层深、上层浅排 |
| count | 字符数量 | 2 到 6 个 | 超过 6 个基本无法辨认 |
| seed | 随机种子 | 任意整数 | 固定后结果可复现 |
关于 jitter 的取值,我做了一个简单的推算。假设画布 2000 像素,字号 620 像素,字符宽度大约是字号的 0.7 倍,也就是 434 像素。如果 jitter 取 0.22 倍字号,即 136 像素,那么两个字符能产生的最大错位距离是 272 像素,这个距离相对于字符宽度 434 像素,比例约 63%——听起来很大,但因为是双向随机的,实际平均重叠率还在合理区间。如果 jitter 取到 0.35,最大错位就会接近字符宽度,字符之间会完全错开,叠字母就变成了"排字母"。
旋转的注意事项是旋转中心。默认以画布中心为轴旋转,会让字符整体绕着中心转,形成放射感;如果以字符自身中心为轴旋转,每个字符就是原地歪头,感觉更轻松随意。这两种效果差别很大,做系列的时候要统一。
4.3 覆盖式叠加与乘算叠压,选哪个
合成方式有两种主流做法,效果完全不同,得按需选择。
覆盖式叠加就是上层直接盖住下层,交叠区显示的是上层的颜色。这种做法干净利落,层次分明,适合标识型设计,因为每一层的轮廓都很清晰。缺点是如果上层不透明,下层的交叠部分信息就完全丢失了,某些笔画会突然断掉。
乘算叠压是把颜色做乘法混合,交叠区会变成两色的混合结果,通常偏暗。这种做法能做出那种老式丝网印、油墨叠印的感觉,交叠区有明确的"第三色",质感更厚。缺点是颜色容易脏,尤其是三种以上混在一起,最后往往是一坨深褐。
代码上,覆盖用合成函数直接叠图就行:
import random from PIL import Image, ImageDraw, ImageFont CANVAS, FONT_SIZE = 2000, 620 FONT_PATH = "./fonts/MY-BOLD.otf" # 换成你本地的粗字重字体 LETTERS = list("ABCDE") random.seed(20240617) # 固定种子,结果可复现 base = Image.new("RGBA", (CANVAS, CANVAS), (0, 0, 0, 0)) font = ImageFont.truetype(FONT_PATH, FONT_SIZE) cx = cy = CANVAS // 2 for i, ch in enumerate(LETTERS): layer = Image.new("RGBA", (CANVAS, CANVAS), (0, 0, 0, 0)) d = ImageDraw.Draw(layer) bbox = d.textbbox((0, 0), ch, font=font) w, h = bbox[2] - bbox[0], bbox[3] - bbox[1] jitter = FONT_SIZE * 0.22 x = cx - w / 2 + random.uniform(-jitter, jitter) y = cy - h / 2 + random.uniform(-jitter, jitter) color = (random.randint(40, 210), random.randint(40, 210), random.randint(40, 210), 255) d.text((x - bbox[0], y - bbox[1]), ch, font=font, fill=color) if i % 2 == 0: layer = layer.rotate(random.uniform(-12, 12), resample=Image.BICUBIC, center=(cx, cy)) base = Image.alpha_composite(base, layer) base.save("stacked.png")这里几个关键点:textbbox拿到的是字符的实际边界框,不是字号框,用它来居中对齐才不会让不同字符歪到一边;center=(cx, cy)指定了旋转中心;alpha_composite是覆盖式合成,后面加的图层盖住前面的。
乘算版本需要一个额外步骤,因为乘算在带透明的图上没有意义,得先把每一层放到白底上再做乘算:
from PIL import Image, ImageChops def multiply_stack(paths, size=2000): acc = Image.new("RGB", (size, size), (255, 255, 255)) for p in paths: layer = Image.open(p).convert("RGBA") white = Image.new("RGBA", layer.size, (255, 255, 255, 255)) layer = Image.alpha_composite(white, layer).convert("RGB") acc = ImageChops.multiply(acc, layer) return acc两种方式都试过之后我的感受是:标识型作品用覆盖式,干净、可预期;肌理型作品用乘算,厚重、有印刷感。如果要做三色以上的乘算,务必把每种颜色的明度拉开,否则十几层乘下来就是一块黑。
4.4 批量产出与命名规范
批量跑的时候,我吃过最大的亏是文件管理。几百张图出来,全是一串随机数命名,过两天自己都认不出哪张是哪张,只能一张张开盲盒。后来我固定了一套命名规则:
[系列名]-[字符组合]-[层数]-[种子]-[色系].png比如seriesA-ABE-3-20240617-warm.png。这套规则里最重要的是种子,只要种子记着,同样的参数随时能重跑出来;其次是层数,因为层数一变视觉感受就完全不一样。系列名前缀用于分组,色系用于快速筛选。
另外,批量出图之后一定要做的一件事是出缩略图预览表。把所有结果拼成一张网格图,一张一张看是看不完的,拼成网格之后哪些不合格一眼就能扫出来。我一般的做法是每批出 40 张,拼成 8×5 的格子,扫一遍淘汰一半,留下的再逐个精修。这个习惯省了我大量时间。
5. 常见问题与排查实录
这部分是我这些年攒下来的问题清单。叠字母的坑其实集中在两类:一类是看着不对但说不清哪不对,一类是文件出问题。分开讲。
5.1 视觉类问题速查
| 现象 | 大概率原因 | 处理方式 |
|---|---|---|
| 整体像一团墨,认不出字 | 层数太多或笔画太粗 | 减到 3 层以内,字重降到 0.12 以下 |
| 缩到小尺寸就糊 | 笔画宽度占比过低,细节过密 | 加大笔画宽度,删掉多余字符 |
| 交叠区一大块死黑 | 重叠面积超 35% | 拉开字符距离,减少重叠 |
| 看着松散、不像一件作品 | 骨架没有对齐,笔画宽度不统一 | 回到统一字重和中心线 |
| 颜色发脏 | 色相跨度太大或乘算层数过多 | 色相收敛到 60 度内,减少乘算层 |
| 交叠区位置不对、构图歪 | 视觉重心偏离中心 | 调整最大重叠块的位置 |
| 白缝碎成麻点 | 字符太密或负空间未规划 | 减层,或者刻意留出一块大的白 |
这张表里最值得说的是第一条和第三条,因为它们是新手最常遇到的,也是最好解决的。反而是"看着松散"这条最难修,因为它不是某个参数错了,而是基础没打好——所有的笔画粗细都在轻微地不一致,单个看不出来,整体就是别扭。这种时候不要试图局部调整,直接回炉重画骨架。
5.2 技术与文件类问题速查
技术上出问题的地方比较集中,主要是路径和颜色两件事。
| 现象 | 原因 | 处理方式 |
|---|---|---|
| 布尔运算后出现孤立小碎片 | 路径边缘有微小缝隙未相交 | 运算前给路径加 0.1mm 描边并转填充 |
| 合并后某块区域填充反了 | 路径方向被翻转 | 用方向修正工具统一方向 |
| SVG 在别的软件打开变样 | 描边未转曲或文字未转路径 | 导出前全部轮廓化 |
| 位图边缘有锯齿 | 缩放时的重采样方式不对 | 用双三次或更高质量的重采样 |
| 印刷出来颜色发闷发暗 | RGB 转 CMYK 导致色彩压缩 | 在 CMYK 下重新调色,提亮 5% 到 8% |
| 交叠区印刷错位 | 用套印处理但未做陷印 | 叠压区留出 0.1mm 的叠印边 |
| 不同批次结果不一致 | 随机种子未固定 | 记录种子并写进文件命名 |
最后那条"不同批次结果不一致"看着不起眼,但真的会要命。有一次做一个系列,做完第一批,隔了一周做第二批,想沿用同样的风格,结果怎么调都不像。翻了半天代码才发现是中间升级过一次库,默认的重采样方式变了,边缘的软硬程度跟着变了。从那以后我所有批量任务的种子、库版本、字体文件路径全部写进一个配置文件,跟结果一起存档。
5.3 几条只有动手才会知道的经验
说几条文档里不会写、但实际做起来很管用的东西。
判断叠得对不对,最好的办法是缩到指甲盖大小看一眼。叠字母中大量的失败案例在放大的时候都挺好看,缩到 32 像素就完蛋。原因是那些漂亮的小交错在大尺寸下是细节,在小尺寸下就变成了模糊的噪点。所以我的自检流程里有一条硬性动作:把成品缩到 32 像素和 64 像素各看一次,两次都能辨认出主字,才算过。
先做单色版,再做彩色版。单色版逼着你解决结构问题,因为颜色一上来,很多结构缺陷会被对比度掩盖掉。等单色版看着舒服了,再去分配颜色,层次一下就出来了。我现在的习惯是所有方案都要先过一遍纯黑稿,过不了纯黑稿的方案,上色也只是把问题藏起来。
别用纯黑和纯白。纯黑(#000000)印在纸上会显得死,缺少呼吸感;纯白的负空间在屏幕上看很干净,印在纸上往往不够透。我的习惯是用接近黑的深灰(明度 8% 到 12%)和接近白的暖白(明度 92% 到 96%),这样出来的东西柔和一些,也更像印刷品而不像屏幕截图。
交叠区的边缘要检查一遍。缩放和旋转之后,两个字符的交叠边会出现一条极其细的亮线或者暗线,原因是抗锯齿的像素没有完全覆盖。这个在缩略图上看不见,放大到 400% 就非常明显。处理办法是在合成前给每个字符的图层加一层 1 像素的羽化,或者干脆在最后叠加一层极轻微的噪点把这条线打散——后者对印刷品反而有好处,会让颜色更均匀。
存档一定留分层文件。因为做完之后你一定会改。客户会说"再往左一毫米",你自己会说"其实这个交叠可以再深一点"。分层文件是唯一的保险,千万不要只存合并后的成品。
6. 叠字母的延展玩法
基础的做法聊完了,说几个我玩过并且觉得值回时间的方向。这些方向本身不算复杂,但能让一个方案变成一整个系列。
6.1 单色版和镂空版是两个完全不同的考题
单色版看着简单,实际上比彩色版难。没有了颜色帮忙分层,所有的层次都得靠形状本身的结构来支持,交叠区只能靠重叠产生的密度差异来暗示。做单色版时有个窍门:让交叠区"实",让非交叠区"虚",具体做法是在非交叠区做一点镂空或者减细——相当于用镂空当浅色,用实心当深色。这种手法在印章、单色丝印里非常经典。
镂空版是另一个思路,把整个图形做成一张剪纸或者一个模板,字符之间靠细细的连接筋相连。这个做法的关键在于连接筋的位置要藏在笔画里,不要横七竖八地搭在空白处。做法是把连接筋跟某个笔画的方向对齐,让它看起来像是笔画的一部分。镂空版特别适合做实物:卡纸刻出来贴在墙上、做喷漆模板、做饼干模具。我用它做过节日卡片,效果比印刷的还讨喜,因为透光本身就有意思。
6.2 让它动起来:帧抖动与逐帧生长
静态的叠字母做完之后,最省力的延展方式就是做动图。两种做法我都试过。
第一种是帧抖动,把同一组参数加上极小的随机扰动,生成 12 到 24 帧,循环播放。字符会有一种轻微呼吸、颤动的感觉,很适合做头像动图或者加载动画。关键是扰动幅度要小,偏移不超过字号的 1%,旋转不超过 0.5 度,超过了就会变成真正的抖动,观感很差。
第二种是逐帧生长,字符一层一层出现,或者从中心向外扩散。这个需要你先规划好出场顺序,我的做法是按 z 轴顺序,从最底层往上逐层显现,每层间隔 3 到 5 帧,最后一层停留的时间长一点。节奏上,先快后慢看起来更自然,因为人的注意力在开头最集中。
做动图的时候有个参数要注意:帧数不要太多。24 帧的循环在文件体积和流畅度之间是个比较好的平衡点,超过 36 帧文件会变大,小尺寸播放时也看不出区别。
6.3 落到材质上:贴纸、印章、丝网、卡纸
最后一个方向是把它做成实物,这个方向的乐趣是屏幕替代不了的。
贴纸是最容易上手的,普通的模切贴纸就行,注意外轮廓要留 2 毫米左右的白边,否则边缘容易翘起、也不好看。印章的控制点在刻线深度和印油的吸收,线条宽度低于 0.8 毫米的细节会糊,所以做印章版的时候要专门做一次简化,把细笔画并粗。丝网印要注意的是套色数量和套准,颜色越多越难对准,两色是甜点,三色就要谨慎了,交叠区还要留叠印边防止露白。卡纸镂空最考验耐心,字符之间的连接筋要足够宽,低于 3 毫米基本一碰就断,我一般留 4 到 6 毫米,具体看卡纸的厚度。
这几样做下来,我发现一个有意思的事:屏幕上的好方案,刻出来往往还要再改一次。因为实物有厚度、有阴影、有接受面,这些在屏幕上是没有的。所以我的建议是,如果你的成品最终要做成实物,那在纸稿阶段就把材质考虑进去,别等到最后再返工。
这个方向我还会继续往下走,下一步想试试用叠字母做一套可以自己拼装的木质字模——把叠好的形状切成小块,用的时候拼起来。可能会遇到的问题是连接处的强度,得在形状和结构之间找一个妥协点。等试出来了,再来更新这一段的实测结果。