字符画艺术
字符画艺术(ASCII ART),是一种用字符来表述图像的视觉艺术。早期打印机擅长文本而非图形,简单的字符(如 ASCII 等)经过精心排列可形成生动有趣的“图形”,由此演化出一种独特的字符画艺术。
字符画有多种类型,包括:
- 符号表情(颜文字)
:-D | 开心
:-( | 不开心
- 拟物
|\_/|
/ @ @ \
( > º < )
`>>x<<´
/ O \
- 艺术文字
_ _
/\ /\___| | | ___
/ /_/ / _ \ | |/ _ \
/ __ / __/ | | (_) |
\/ /_/ \___|_|_|\___/
- 图片
本文介绍艺术文字和图片的字符画生成方法。
艺术字
对于艺术字,有许多现成的库供选择,但遗憾尚未发现支持中文的相关库。 pyfiglet 是众多选择之一,它内置丰富多样的字体供选择。
>>> import pyfiglet
>>> def ascii_text(content, font='isometric1'):
... result = pyfiglet.figlet_format(content, font=font)
... return result
...
>>> ascii_text('Python', 'isometric1')
___ ___ ___ ___ ___ ___
/\ \ |\__\ /\ \ /\__\ /\ \ /\__\
/::\ \ |:| | \:\ \ /:/ / /::\ \ /::| |
/:/\:\ \ |:| | \:\ \ /:/__/ /:/\:\ \ /:|:| |
/::\~\:\ \ |:|__|__ /::\ \ /::\ \ ___ /:/ \:\ \ /:/|:| |__
/:/\:\ \:\__\ /::::\__\ /:/\:\__\ /:/\:\ /\__\ /:/__/ \:\__\ /:/ |:| /\__\
\/__\:\/:/ / /:/~~/~ /:/ \/__/ \/__\:\/:/ / \:\ \ /:/ / \/__|:|/:/ /
\::/ / /:/ / /:/ / \::/ / \:\ /:/ / |:/:/ /
\/__/ \/__/ \/__/ /:/ / \:\/:/ / |::/ /
/:/ / \::/ / /:/ /
\/__/ \/__/ \/__/
>>> ascii_text('Python', '5lineoblique')
// ) )
(( ___ / __ ___ _ __ ___
\\ // ) ) // ) ) //___) ) // ) ) ) ) //___) )
) ) // // / / // // / / / / //
((___ / / ((____ // / / ((____ // / / / / ((____
pyfiglet
生成字符的原理并不神秘,字体文件中已经包含每个字母的字符画,程序只需使用相应的字体包来生成目标单词的字符画即可。
图片
原理很简单:将图片颜色转化成灰度,然后像素点映射到一组字符上。字符序列 ascii_char
的呈现着色递减的趋势。函数 ascii_img
接收图片链接,返回字符串。与像素格不同,字符的长宽比不是 1:1, fix_rate
用来调节长宽比。可选参数 point_num
用来设置字符数。
ascii_char = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "
def get_char(r, g, b, alpha=256):
if alpha == 0:
return ' '
length = len(ascii_char)
gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
unit = (256.0 + 1) / length
return ascii_char[int(gray/unit)]
def get_image(url):
response = requests.get(url, timeout=2)
image = Image.open(BytesIO(response.content))
return image
def ascii_img(url, fix_rate, point_num = 8000):
im = get_image(url)
rate = im.size[0]/im.size[1] * fix_rate
height = int(math.sqrt(point_num / rate))
width = point_num // height
im = im.resize((width, height), Image.NEAREST)
txt = ""
for i in range(height):
for j in range(width):
txt += get_char(*im.getpixel((j,i)))
txt += '\n'
return txt
对于颜色区分大、内容简单的图片,字符生成结果很好。下面是两个示例: