跳到主要内容

图片转字符画原理与实战:把任意图片变成 ASCII 字符艺术

讲清楚图片转 ASCII 字符画的核心原理:像素亮度怎么映射到字符密度。再讲字符集怎么选、分辨率多少合适、等宽字体怎么显示,附一张真实图片的完整转换设置。

发布于 作者 李雷
#字符画 #ASCII #图片转换 #终端

图片转字符画原理与实战:把任意图片变成 ASCII 字符艺术

字符画看着像玄学,其实背后只有一个朴素的想法:一张图无非是一格一格的明暗,而 @. 更"黑"。把图片的明暗对上字符的疏密,字符画就出来了。这篇把这件事拆开讲明白:亮度怎么算、为什么要映射到字符密度、字符集和分辨率怎么挑、最后等宽字体这关怎么过。

核心原理:像素亮度映射到字符密度

整个转换只做一件事,把每个像素的亮度对应到一个字符。

第一步是算亮度。RGB 三个通道不能简单取平均,因为人眼对绿色最敏感、对蓝色最迟钝。业界通用的是 Rec. 709 灰度公式:亮度 = 0.2126 × R + 0.7152 × G + 0.0722 × B。绿色权重最高,蓝色几乎可以忽略,算出来的灰度才贴近肉眼的明暗感受。

第二步是把这个 0 到 255 的亮度,映射到一串按疏密排好的字符上。最经典的是 Paul Bourke 的 10 阶字符串 .:-=+*#%@,从空格(最疏、最亮)一路到 @(最密、最暗)。一个亮度 30 的暗像素落在 @ 附近,一个亮度 220 的亮像素落在空格或 . 附近。这就是"亮度映射到字符密度":暗的地方字符笔画多、占的墨多,看起来就深;亮的地方留白多,看起来就浅。整张图扫一遍,字符画的轮廓自然浮现。

有一个容易踩的坑是透明像素。带透明背景的 logo,如果不处理透明通道,镂空的地方会被当成纯黑,直接糊成一团黑。正确做法是先把半透明像素和白底预合成,再去算亮度,镂空才会变白而不是变黑。

字符集:10 / 16 / 32 阶分别什么时候用

字符集决定了你的"调色板"有多少级灰度。

10 阶适合线稿、logo、像素艺术,边缘清晰、颗粒感强,就是上面那个 Bourke 字符串。16 阶适合一般照片,人脸和天空的过渡会更顺,多出来的字符专门用来抹平中间调。32 阶给人像和暗部细节多的图用,密集字符表在暗部塞得更密,而暗部恰恰是照片信息最集中的地方。

字符的排列顺序非常关键,必须从浅到深排。如果你自定义字符集时按"深到浅"排,整张图会像照片负片一样反过来,亮的天空会变成一片 @。想用自己的名字或 emoji 当画笔也行,比如把名字小写从浅到深输进去,整张图会用这几个字母重新拼出来。

分辨率:宽度多少列合适

字符画的"分辨率"就是输出多少列字符。列数越多越细腻,但也越占地方。

经验上,贴进 80×24 终端的横幅,宽度 60 列比较稳;GitHub README 顶部的人像,100 列左右脸还认得出;离职卡片这种要打印的,可以拉到 120 甚至更高。这里有个反直觉的点:原图分辨率高到一定程度后再加大没意义。采样画布内部通常会把最长边压到 400 像素左右,超过这个分辨率的图,出来的字符画其实一模一样,真正决定细腻度的是你设的列数,不是原图多少万像素。

等宽字体:让字符画不变形

字符画对字体有硬要求,必须等宽。

比例字体里 im 宽,每个字符占的横向空间不一样,对齐立刻全乱。所以输出一定要包进围栏代码块或 <pre> 标签,每个字符才占固定一格。把它贴进普通 Markdown 段落是最常见的翻车方式。

还有一个纵向压扁的问题。等宽字体一格的高度大概是宽度的两倍,如果 50×50 像素原样画成 50×50 字符,纵向会被拉长一倍。好的工具会自动把行数砍半补偿。万一你的终端字体比例偏扁,可以在 <pre> 上加 line-height: 0.8 收紧。

一个真实例子:头像转 GitHub README 马赛克

说一下我自己常用的设置。我想在 README 顶部放一张白底渲染的头像字符画,流程是这样:

上传头像,宽度设 100,打开反色,字符集选 32 阶。为什么开反色?默认是按深色终端映射的,暗像素配密字符。但 GitHub 的 README 是白底,不开反色贴上去会像照片负片。开了反色之后,暗像素配疏字符,在白底上一样能认出脸。字符集选 32 阶是为了保住脸部中间调,人脸的信息大半在中间调上。最后把结果包进围栏代码块,等宽间距才不会塌,大概 100×50 个字符,脸清清楚楚。整段纯文本几 KB,零图片请求,断网也能渲染出来。

小结

图片转字符画的核心就一句话:用 Rec. 709 算出每个像素的亮度,再把亮度映射到一串从疏到密排好的字符上。剩下的都是调味,字符集决定灰度级数,列数决定细腻度,等宽字体和围栏代码块保证不变形。想直接上手,打开 图片转 ASCII 字符画工具 拖一张图进去就行;如果你想从纯文字而不是图片生成横幅,可以试试 ASCII 字符画生成器


Made by Toolora · Updated 2026-06-13