AIGC标识 照片转 ASCII 字符画:拖一张图,黑白字符拼出你的脸

一张普通照片,拖进网页几毫秒就变成由 .:-=+*#%@ 这些字符拼成的画,宽度、字符集、亮度和对比度都能随手调,还能一键复制字符画或导出 PNG/TXT。整个过程纯前端完成,图片不会上传到任何服务器。先看成品,再讲这次怎么用华为云 CodeArts 码道 WebUI 一段话把它做出来、部署并公开分享。

这个工具做什么

它把「图片像素」翻译成「灰度字符」,做成了一个本地即用的 ASCII 字符画工具:

  • 拖拽上传:拖图或点选图片都行,支持 PNG / JPG / WEBP / GIF,右侧实时预览字符画。
  • 可调输出宽度:滑块从 20 到 240 个字符,越宽细节越多,越窄越有极简味道。
  • 6 套字符集:标准(10)、精细(70)、带块、色块、圆点,以及自定义字符集,灰度层次随字符数变化。
  • 亮度 / 对比度:两个独立滑块,照片太暗或灰度拉不开时现场调整,不必回去重改原图。
  • 反色 + 彩色字符画:黑底白字 / 白底黑字一键切换,彩色模式会按原图颜色给每个字符上色。
  • 导出:一键复制字符画到剪贴板,或下载 TXT、PNG,PNG 是用 Canvas 重新渲染出来的等宽字符图。

照片转 ASCII 字符画运行界面

码道开通(免费体验版)

开始之前,先免费开通码道体验版。不需要装任何软件,浏览器就能用:

https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwsf&sourcead=dmzntgwwbwz

开通后有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版演示。

进入 AI 开发者空间

  1. 浏览器打开 https://devstation.developer.huaweicloud.com/aidevspace?utm_source=opcsfsq&utm_medium=wbwz
  2. 弹窗「请选择要进入的版本」→ 点击 体验版
  3. 首次使用会跳到华为云登录页,扫码登录一次,后续浏览器会话复用
  4. 弹窗「临时凭据自动配置」→ 点击 同意,沙箱自动创建

进入 AI 开发者空间主界面后,先等左侧菜单加载出来,再找到 CodeArts,点击它右侧的浏览器图标,打开码道 WebUI 对话窗口:

AI 开发者空间主界面

打开后码道 WebUI 底部输入框提示「尽管吩咐,我来帮你搞定」:

码道 WebUI 对话窗口

小贴士:体验版沙箱 3 小时后自动重置,生成完记得把 index.html 下载保存。

任务描述

在码道 WebUI 输入框粘贴以下需求,回车发送(模型默认 glm-5.2,可直接用):

开发一个「照片转 ASCII 字符画」网页应用:用户可以上传或拖入一张图片,应用把图片转换成由黑白 ASCII 字符组成的字符画,可调整输出宽度、字符集、亮度/对比度,支持一键复制字符画和下载 PNG/文本,界面简洁美观,单个网页打开即用。完成后用部署功能部署成可访问的网页应用,并告诉我访问地址。

输入需求后开始生成

这轮码道具体做了什么

不是把通用 AI 能力复述一遍,而是它在这篇项目里的实际动作:

  • 读取沙箱路径后,在 /workspace/ascii-art 下新建项目目录,并清掉了残留的旧目录。
  • 发现 PYTHONHOME 指向了码道自带的 python3.12 会导致端口检测异常,改用纯 bash 的 /dev/tcp 探测空闲端口,启动服务时再清掉相关环境变量。
  • 写入约 558 行的单文件 index.html(原生 HTML/CSS/JS,零依赖),包含图像读取、灰度采样、亮度对比度、字符集切换、复制与 Canvas 导出等完整逻辑。
  • 检测到 3000 端口空闲,用 python3 -m http.server 3000 --bind 0.0.0.0 --directory /workspace/ascii-art 起服务,curl 自检通过后给出内部预览地址。

代码亮点

以下是 index.html 里值得关注的设计思路和实现细节。

1. 用加权灰度把像素映射到字符

图片先画到 Canvas 上,再 getImageData 逐像素采样。每个像素先做 Alpha 混合到黑底,再用标准亮度公式转灰度,最后按灰度值落到字符集数组的对应下标:

const gray = 0.299 * r + 0.587 * g + 0.114 * b;
let idx = Math.floor((gray / 255) * n);
if (idx >= n) idx = n - 1;
if (idx < 0) idx = 0;
const ch = chars[idx];

2. 亮度对比度在采样前先处理像素

对比度不是简单乘系数,而是套用标准对比度公式 (259*(C+255))/(255*(259-C)),再叠加亮度偏移:

const cf = (259 * (contrast + 255)) / (255 * (259 - contrast));
r = clamp(cf * (r - 128) + 128 + brightness);
g = clamp(cf * (g - 128) + 128 + brightness);
b = clamp(cf * (b - 128) + 128 + brightness);

3. 彩色字符画和反色

默认是黑白字符,开启「彩色字符画」后,每个字符用 <span> 单独着色,颜色就是原图对应像素的颜色;「反色」则把 RGB 三点都取反,实现黑底白字 / 白底黑字切换:

const col = invert ? `rgb(${255 - c.r},${255 - c.g},${255 - c.b})` : `rgb(${c.r},${c.g},${c.b})`;
html += `<span style="color:${col}">${escapeHtml(c.ch)}</span>`;

4. 复制与 PNG 导出

复制优先用 navigator.clipboard,失败再降级到 execCommand('copy')。下载 PNG 则直接按字符网格重画一张 Canvas,用等宽字体逐格 fillText,再 toBlob 下载:

ctx.font = `${fontSize}px "Courier New", Consolas, monospace`;
for (let y = 0; y < rows; y++) {
  for (let x = 0; x < cols; x++) {
    const c = cells[y * cols + x];
    ctx.fillText(c.ch, pad + x * charW, pad + y * charH);
  }
}

直接下载试玩

本次生成的项目就是单文件 index.html,没有第三方依赖,把文件保存到本地后双击用浏览器打开即可运行。源码同步到公开 Demo Park 仓库:

总结

照片转 ASCII 字符画这一步,把「图片处理」这件事拆成了清晰的三段:像素采样、灰度/亮度/对比度映射、字符渲染与导出。技术上是 Canvas getImageData 逐像素处理,再加上字符集和反色/彩色两处显示层切换,前后端都不碰服务器,图片隐私也更安心。后续还可以加批量拖图、去色阈值或按区域黑白化。

如果还没用过码道,可以免费开通体验版:https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwsf&sourcead=dmzntgwwbwz

posted @ 2026-09-04 09:04  新科技观察员  阅读(7)  评论(0)    收藏  举报