图片字符画

图片→ASCII 字符画/彩色字符

420 次访问

图片转字符画 · ASCII Art

🔤
拖入 / 点击 / 粘贴图片
JPG / PNG / WebP / GIF · 浏览器本地处理,不上传
支持 Ctrl/Cmd + V 粘贴 · 或试用下方预设案例 ↓

使用提示

· 宽度 / 高宽比:宽度决定细节,高宽比补偿等宽字体"高宽 ≠ 1:1"——默认 0.50 适合大多数等宽字体(含 ui-monospace / Menlo / Consolas)。若导出后纵向被压扁可调到 0.55–0.60

· 字符集:从左到右"暗→亮"递增。"标准 70 级"细节最丰富;"块字符 █▓▒░ "像素感最强;"中文方块 ▮▤■"在终端更醒目;"表情 😀🌟"做艺术海报很出彩

· 灰度算法:人眼对绿色更敏感,加权(默认)最接近视觉感受;平均更素朴;Rec.709 是高清电视标准;明度偏冷淡

· 采样算法平均=经典灰阶;边缘=Sobel 算子提线稿(适合速写 / 漫画);暗部 / 亮部=单极阈值化(适合剪影 / 透明背景)

· 伽马 / 二值:伽马 <1 提亮中间调(暗部细节),>1 压暗高光;二值阈值大于 0 时直接黑白二色,适合 logo 风

· 颜色模式:纯黑白可粘到任何聊天框;HTML 灰度 / 彩色保留原色调,需用浏览器或 .html 下载查看

· PNG 导出:把字符画渲染为图片(高 DPI),保留背景配色,分享朋友圈不丢字

· 字号 / 行高:滑块只影响当前预览,不影响 .txt / .html 内容本身(导出始终原样)

关于本工具

了解工具定位 · 使用场景 · 对比优势

将图片转为由字符组成的黑白或彩色画作,保留原图的轮廓与明暗层次。适合制作社交媒体头像、程序员趣味素材、或是给文本环境增加视觉点缀。上传图片后,在浏览器内完成转换,图片不会上传到服务器。

使用场景

🎨

程序员博客封面

技术博主在写后端教程时,想用一张代码截图做封面但担心版权或太单调。将截图上传后转成 ASCII 字符画,保留代码轮廓的同时增加极客感,适合黑白极简风格的博客。无需 PS,浏览器内直接生成并复制。

🎮

游戏直播封面图

游戏主播需要一张与众不同的直播间封面,但手绘能力有限。截取游戏角色或场景,转换成彩色字符画,既保留原图色彩辨识度,又形成独特的像素风视觉冲击,吸引观众点击。生成后直接截图使用,无需安装软件。

💻

终端欢迎屏定制

Linux / macOS 开发者想给终端(Terminal)设置个性化的欢迎画面(motd / neofetch 替代)。上传个人 Logo 或喜欢的图案,转成纯 ASCII 字符画(无颜色),粘贴到 .bashrc 或 .zshrc 中,每次打开终端都能看到专属字符图,增强工作仪式感。

📱

社交媒体个性签名

微信 / Twitter / Discord 用户想在个人简介或状态栏放一个独特的小图标,但平台只支持纯文本。上传一张简单的头像或符号(如猫、星球、箭头),转成短字符画(宽度 ≤ 40 字符),复制粘贴到签名区,形成一眼可识别的个人标识。

🎁

手工贺卡内页装饰

DIY 爱好者制作纸质贺卡时,想加入一张有意义的照片但印刷成本高。用工具将合照或宠物照片转成灰度字符画,打印后贴在贺卡内页,黑白打印即可呈现细腻层次,比直接贴照片更有手工感和温度。

对比矩阵本工具 vs 竞品 vs 传统方法

维度本工具竞品 A (asciiart.club)传统方法 (手工绘制)
数据隐私纯浏览器,零上传,图片不离开设备上传图片到服务器处理图片完全本地,无网络传输
处理速度1 秒内出结果5-10 秒(含上传+排队)数小时至数天(人工逐像素绘制)
离线可用完全离线,断网可用必须联网完全离线
彩色支持支持彩色字符输出(保留原图色彩)仅支持灰度/黑白字符取决于绘制者能力,可彩色
输出格式直接复制字符文本,或下载为文本文件仅网页预览,需手动截图保存物理纸张或数字画布
使用门槛零学习成本,上传即用需注册账号需具备绘画功底和大量时间

使用指南

上手步骤 · 输入输出 · 避坑提示

使用步骤

  1. 上传或拖入一张图片(支持 JPG/PNG/WebP,单张 ≤ 10MB)
  2. 选择输出样式:黑白 ASCII 或彩色字符,调整字符密度滑块(1-10)
  3. 点击「生成字符画」按钮,预览区实时显示转换结果
  4. 点击「复制文本」复制 ASCII 字符,或「下载图片」保存为 PNG

输入输出示例6 个典型场景,覆盖常规、边界与易错

输入输出说明
一张纯白背景、黑色线条的简笔画小猫(PNG,200x200 像素)生成的 ASCII 字符画:由 @、#、*、. 等字符组成的小猫轮廓,背景为空格。典型场景:高对比度简笔画,字符画轮廓清晰
一张色彩丰富的风景照片(JPG,1920x1080 像素)生成的彩色字符画:每个字符带有对应像素的 ANSI 颜色代码,整体呈现彩色马赛克效果。典型场景:彩色照片转为彩色字符画,保留色彩信息
一张纯黑色图片(PNG,100x100 像素)生成的 ASCII 字符画:整个画面由同一个字符(如 @ 或 #)铺满,无明暗变化。边界 case:纯色图片,字符画失去纹理细节
一张尺寸极小(10x10 像素)的图标(PNG)生成的字符画:仅 10 行 10 列字符,能辨认出基本形状但细节丢失严重。边界 case:极小图片,输出字符画分辨率极低
一张包含渐变过渡的灰度图(PNG,500x500 像素)生成的 ASCII 字符画:使用 @%#*+=-:. 等字符模拟灰度渐变,过渡平滑。典型场景:灰度图,字符画能表现明暗层次
一张包含大量文字和数字的截图(PNG,800x600 像素)生成的字符画:文字区域被字符覆盖,原始文字内容无法辨认,仅保留形状。易错 case:用户误以为字符画能保留文字可读性

常见错误对照7 个常踩的坑 · 错误 → 修复

1. 上传了透明背景 PNG 但期望黑色背景

错误
上传一张透明背景的 logo.png,结果字符画背景全是黑色方块,看不到图案
修复
上传前先用图片编辑工具把透明区域填充为白色或纯色背景,或选择工具提供的“强制背景色”选项

ASCII 字符画本质是灰度映射;透明像素的 RGBA 值为 (0,0,0,0),亮度计算时 Alpha=0 导致全黑,不是工具 bug

2. 上传超大图片(5000×5000)导致浏览器卡死

错误
直接拖入一张 20MB 的 4K 照片,页面无响应 30 秒后崩溃
修复
先用图片压缩工具把图片缩放到 800×600 以内,或使用工具自带的“最大宽度/高度”限制输入

字符画生成需要逐像素计算亮度并映射到字符矩阵,O(n) 复杂度下 5000×5000 = 2500 万像素,浏览器主线程会阻塞

3. 把彩色字符画的结果直接复制到纯文本编辑器

错误
点击“复制”后粘贴到记事本,只看到一堆乱码字符,没有颜色
修复
彩色字符画使用 HTML/CSS 或 ANSI 转义序列表示颜色;复制后应粘贴到支持富文本的编辑器(如 Word/VS Code)或使用工具提供的“导出为 HTML”功能

纯文本(.txt)不支持任何颜色标记;ANSI 转义序列在终端中可见,在记事本中显示为原始字符

4. 用手机横屏拍的照片直接上传,字符画方向不对

错误
手机拍了一张竖屏照片,生成的字符画是横着的,人物躺倒了
修复
上传前先用系统相册或图片工具把照片旋转到正确朝向(EXIF 方向已修正),或选择工具提供的“旋转 90°”预处理选项

手机照片的 EXIF 方向元数据会被浏览器忽略;Canvas 读取原始像素矩阵时不会自动旋转,需要用户手动处理

5. 上传纯黑或纯白图片,字符画全是同一个字符

错误
上传一张纯黑色 #000000 图片,结果输出全是 '@' 或全屏空格,看不出任何内容
修复
选择有明暗变化的图片(如人物照片、风景照),或上传后手动调整“对比度”滑块增加灰度层次

字符画映射依赖像素亮度差异;纯色图片所有像素亮度相同,只能映射到同一个字符,无法形成图案

6. 把 GIF 动图当成静态图上传,只处理了第一帧

错误
上传一个 10 帧的 GIF 表情包,生成的字符画只显示了第一帧的内容
修复
GIF 动图需要逐帧处理;如果工具不支持多帧,先用视频转 GIF 工具提取关键帧,或上传静态 PNG/JPG 版本

浏览器 Canvas 的 getImageData() 默认只读取当前帧;多帧处理需要额外解码库(如 gif.js),大部分在线工具未实现

7. 期望字符画和原图完全一样精细

错误
上传一张 100×100 的缩略图,抱怨生成的字符画看不清人脸细节
修复
使用 200×200 以上分辨率的图片,并选择“精细”字符集(如 70 级灰度字符)而非默认的 10 级字符集

每个字符占据约 8×12 像素的屏幕空间;原图分辨率越低,字符画能表达的细节越少,这是采样定理的物理限制

工作原理

公式推导 · 流程图解 · 依据出处

核心公式

G = Σᵢ (Lᵢ × Cᵢ) / N

变量说明

  • G — 目标像素的灰度值(0-255)
  • Lᵢ — 第 i 个通道的亮度系数(如 R=0.299)
  • Cᵢ — 第 i 个通道的颜色值(0-255)
  • N — 通道数量(通常为 3,RGB)

示例

将 RGB 像素 (R=120, G=200, B=80) 转为灰度:G = (0.299×120 + 0.587×200 + 0.114×80) / 3 ≈ (35.88 + 117.4 + 9.12) / 3 ≈ 162.4 / 3 ≈ 54.1。取整后灰度值 54,对应字符 '#'(暗色区域)。

适用范围

基于 ITU-R BT.601 标准亮度公式,适用于标准 RGB 色彩空间(sRGB/Rec.709)。对广色域(如 Adobe RGB)或高动态范围(HDR)图像误差较大,需先转换色彩空间。

原理图

上传图片JPG / PNG / GIF≤ 5MB灰度化 + 采样Canvas 逐像素读取亮度 → 字符映射字符网格生成ASCII / 彩色字符保留原像素颜色预览 / 下载复制或保存为 .txt所有处理在浏览器本地完成,图片不上传服务器支持调整字符密度 / 字符集 / 颜色模式用户输入本地处理输出结果展示 / 导出
用户输入 本地处理 输出结果 展示 / 导出

开发者集成

3 种主流语言 · 复制即用

from PIL import Image

# 将图片转为灰度 ASCII 字符画(亮度映射)
img = Image.open('input.jpg').convert('L')  # 转灰度
width, height = 80, 40
img = img.resize((width, height))

# 字符集从暗到亮
chars = '@%#*+=-:. '
pixels = list(img.getdata())

# 每个像素亮度 0-255 映射到字符索引
result = ''
for i, p in enumerate(pixels):
    idx = p * (len(chars) - 1) // 255
    result += chars[idx]
    if (i + 1) % width == 0:
        result += '\n'

print(result)
package main

import (
	"fmt"
	"image"
	_ "image/jpeg"
	"os"
)

func main() {
	f, _ := os.Open("input.jpg")
	defer f.Close()
	img, _, _ := image.Decode(f)

	bounds := img.Bounds()
	w, h := 80, 40
	scaleX := float64(bounds.Dx()) / float64(w)
	scaleY := float64(bounds.Dy()) / float64(h)

	chars := "@%#*+=-:. "
	for y := 0; y < h; y++ {
		for x := 0; x < w; x++ {
			// 取采样点像素的灰度值
			px := int(float64(x)*scaleX + scaleX/2)
			py := int(float64(y)*scaleY + scaleY/2)
			r, g, b, _ := img.At(px, py).RGBA()
			gray := (r*299 + g*587 + b*114) / 1000 >> 8
			idx := gray * (len(chars) - 1) / 255
			fmt.Print(string(chars[idx]))
		}
		fmt.Println()
	}
}
// 浏览器端:Canvas 读取图片像素生成 ASCII
const img = new Image();
img.src = 'input.jpg';
img.onload = () => {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  const w = 80, h = 40;
  canvas.width = w;
  canvas.height = h;
  ctx.drawImage(img, 0, 0, w, h);

  const imageData = ctx.getImageData(0, 0, w, h);
  const pixels = imageData.data;
  const chars = '@%#*+=-:. ';
  let result = '';

  for (let y = 0; y < h; y++) {
    for (let x = 0; x < w; x++) {
      const idx = (y * w + x) * 4;
      // 灰度 = 0.299R + 0.587G + 0.114B
      const gray = (pixels[idx] * 299 + pixels[idx+1] * 587 + pixels[idx+2] * 114) / 1000;
      const charIdx = Math.floor(gray * (chars.length - 1) / 255);
      result += chars[charIdx];
    }
    result += '\n';
  }
  console.log(result);
};

常见问题

8 个高频疑问

上传图片后怎么操作?点哪里生成字符画?
上传图片后,工具会自动在页面下方或侧边区域生成预览结果。如果图片较大或分辨率较高,生成可能需要等待几秒(全部在浏览器内计算,无需上传服务器)。生成后,结果区域通常会显示纯 ASCII 字符画和彩色字符画两种版本,可以直接复制文本或截图保存。部分实现会提供字符密度、字体大小等调节选项,可以在生成前调整参数再试。
为什么生成的字符画很模糊,看不清是什么?
模糊通常由两个原因造成:一是原图分辨率太低(建议至少 200×200 像素),字符画用单个字符代替像素块,原图细节太少时会丢失形状;二是输出字符宽度限制(比如只用了 80 列字符),字符画的总宽度越窄,细节越少。可以换一张清晰的原图,或在工具设置里增加输出字符列数(如调到 120 或 150 列),同时缩小字符本身的大小,让画面更精细。
这个工具支持彩色字符画吗?还是只有黑白?
本工具同时支持纯 ASCII 黑白字符画和彩色字符画两种输出。彩色版本会保留原图的像素颜色,用带颜色的字符或 HTML 标签(如 <span style=“color:#FF0000”>M</span>)来呈现,适合展示渐变和丰富色彩的图片。黑白版本则只根据亮度映射到不同字符(如 @%#*+! 等),更适合强调轮廓和纹理。输出时一般会并列展示两种结果,方便对比选择。
生成的字符画能保存下来吗?怎么保存?
可以保存。字符画生成后,结果区域通常是纯文本或带颜色标签的 HTML 文本。纯文本版本可以直接全选复制(Ctrl+A 再 Ctrl+C),粘贴到记事本、Word、代码编辑器或社交媒体中。彩色版本如果以 HTML 形式展示,可以复制整个 HTML 片段,或截图保存为图片。部分工具也提供“复制结果”或“下载为 .txt 文件”按钮,点击即可保存到本地。
上传的图片会被存到服务器上吗?隐私安全吗?
不会上传到任何服务器。本工具完全在浏览器端(JavaScript)处理,图片从上传到生成字符画的全部计算都在本地进行,不经过任何网络请求。可以打开浏览器开发者工具(F12)的“网络”面板,在上传图片后观察是否有 HTTP 请求发出——正常情况下没有任何请求。关闭页面后,图片数据会从内存中自动清除,没有残留。如果不放心,可以断网后使用,工具依然能正常工作。
支持什么格式的图片?GIF 动图可以吗?
通常支持常见的静态图片格式:JPEG、PNG、BMP、WebP 等。GIF 动图一般不支持逐帧转换,因为字符画工具只处理单帧图像。如果上传 GIF,大多数实现只会读取第一帧生成静态字符画。如果需要动图字符画(逐帧显示),需要专门的逐帧处理工具。另外,文件大小建议控制在 5MB 以内,超大图片可能导致浏览器卡顿或内存溢出。
手机浏览器上能用吗?操作方便吗?
手机浏览器可以正常使用,但体验受屏幕尺寸影响。字符画宽度(列数)固定时,手机上可能需要左右滑动才能看到完整画面。建议在手机上使用前,先在工具设置里把输出列数调小(如 60 列),让字符画适配手机屏幕宽度。上传图片时,手机相册直接选择即可,大部分工具支持触屏点击上传。如果生成后复制文本,长按结果区域通常能弹出“全选”和“复制”选项。
跟那些用 Python 脚本生成的字符画有什么区别?
本工具是纯 Web 版,无需安装 Python 或任何库,打开浏览器就能用。Python 脚本(如 PIL + argparse)通常功能更丰富:可以自定义字符集、调整对比度、批量处理多张图片、输出不同格式(HTML、SVG、ANSI 等)。但需要命令行操作,对非程序员不友好。Web 版牺牲了部分自定义能力,换来零门槛和跨平台(手机、平板、电脑都能用)。如果只是偶尔做一两张图,Web 版更方便;如果批量处理或需要精细控制,建议用 Python 脚本。
选择 打开 +新窗口 esc关闭