本文目录导读:

Python方案(最常用)
使用PIL/Pillow
from PIL import Image
import numpy as np
def image_to_ascii(image_path, width=100, char_set=None):
"""
将图片转换为字符画
"""
if char_set is None:
# 从暗到亮的字符集
char_set = '@%#*+=-:. '
# 打开图片并转换为灰度
img = Image.open(image_path).convert('L')
# 计算高度(保持宽高比)
aspect_ratio = img.height / img.width
height = int(width * aspect_ratio * 0.5) # 0.5是因为字符通常是宽的两倍
# 调整图片大小
img = img.resize((width, height))
# 将图片转换为数组
pixels = np.array(img)
# 将像素值映射到字符
ascii_art = ""
for row in pixels:
for pixel in row:
# 将0-255的像素值映射到字符索引
index = int((pixel / 255) * (len(char_set) - 1))
ascii_art += char_set[index]
ascii_art += '\n'
return ascii_art
# 使用示例
result = image_to_ascii('input.jpg', width=80)
print(result)
# 保存到文件
with open('output.txt', 'w') as f:
f.write(result)
增强版(支持彩色)
from PIL import Image
import numpy as np
def image_to_ascii_color(image_path, width=80):
"""
彩色字符画版本(使用ANSI颜色码)
"""
img = Image.open(image_path)
ascii_chars = '@%#*+=-:. '
aspect_ratio = img.height / img.width
height = int(width * aspect_ratio * 0.5)
img = img.resize((width, height))
img_rgb = np.array(img)
# 转换为灰度用于选择字符
img_gray = np.array(img.convert('L'))
ascii_art = []
for y in range(height):
line = []
for x in range(width):
# 选择字符
char_index = int((img_gray[y][x] / 255) * (len(ascii_chars) - 1))
char = ascii_chars[char_index]
# 获取RGB颜色
r, g, b = img_rgb[y][x][:3]
# ANSI颜色码
line.append(f"\033[38;2;{r};{g};{b}m{char}\033[0m")
ascii_art.append(''.join(line))
return '\n'.join(ascii_art)
命令行工具(无代码)
使用jp2a(Linux/Mac)
# 安装 sudo apt-get install jp2a # Debian/Ubuntu brew install jp2a # Mac # 使用 jp2a --width=80 input.jpg jp2a --colors --width=80 input.jpg # 彩色
使用chafa
# 安装 sudo apt-get install chafa # 使用 chafa -s 80x40 input.jpg chafa --colors=256 input.jpg
JavaScript(浏览器端)
<!DOCTYPE html>
<html>
<body>
<canvas id="canvas" style="display:none"></canvas>
<pre id="output"></pre>
<script>
function imageToAscii(inputFile) {
const reader = new FileReader();
reader.onload = function(e) {
const img = new Image();
img.onload = function() {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const width = 80;
const aspectRatio = img.height / img.width;
const height = Math.floor(width * aspectRatio * 0.5);
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
const imageData = ctx.getImageData(0, 0, width, height);
const asciiChars = '@%#*+=-:. ';
let asciiArt = '';
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const offset = (y * width + x) * 4;
const gray = (imageData.data[offset] +
imageData.data[offset+1] +
imageData.data[offset+2]) / 3;
const index = Math.floor((gray / 255) * (asciiChars.length - 1));
asciiArt += asciiChars[index];
}
asciiArt += '\n';
}
document.getElementById('output').textContent = asciiArt;
}
img.src = e.target.result;
}
reader.readAsDataURL(inputFile);
}
</script>
</body>
</html>
Bash脚本(使用已有工具)
#!/bin/bash
# 图片转字符画脚本
input_file="$1"
width="${2:-80}"
# 检查图片是否存在
if [ ! -f "$input_file" ]; then
echo "文件不存在"
exit 1
fi
# 检查是否安装jp2a
if command -v jp2a &> /dev/null; then
jp2a --width="$width" "$input_file"
elif command -v chafa &> /dev/null; then
chafa -s "${width}x$((width/2))" "$input_file"
else
echo "请安装jp2a或chafa"
exit 1
fi
使用建议
-
选择字符集:不同的字符集可以产生不同的效果
- 高对比度:
- 更细致:
'$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^'. '`
-
调整宽度:根据终端大小调整输出宽度
-
图片预处理:对于复杂的图片,可以先降噪或增加对比度
-
终端字体:使用等宽字体效果最好
如果你需要更具体的功能(比如视频转字符动画、实时摄像头转换等),告诉我,我可以提供更多方案!