欢迎访问集智主站:集智,通向智能时代的引擎浏览器
本文全部代码都可在集智原贴中运行调试,有须要的同窗能够点击这里前往原贴
bash
ASCII的全称是American Standard Code for Information Interchange,即美国信息交换标准码。是由军用电报编码发展而来,并成为最通用的现代计算机编码系统。网络
在显卡还不能摧毁航母战斗群的年代,计算机还主要用来计算导弹弹道和卫星轨道,其图形处理能力是很是弱的,甚至还不现在天高级一点的示波器。但这并不能阻止人类对美的追求,正如四万年前的莽荒也没有耽误拉斯科洞窟壁画的诞生。编辑器
在我刚上网那阵,有个流传很广的帖子,是教你观看命令行里的《星球大战》,而这部星战正是由ASCII编码中的字符构成的,这被称做ASCII art函数
在斗图代替打字、点播变成直播甚至VR/AR的今天,图形的处理已经再也不是瓶颈,反而成为了新的增加点。道高一尺魔高一丈,技术的进步也带来了有害信息,好比广你们长朋友们特别关注的色情信息。刚开始色情的鉴定是由人工完成的,李迪同志就是在《暴走大事件》中扮演鉴黄师唐马儒而一炮走红。post
可是,基于人工智能的图像识别也在飞速进步,自动鉴黄已经投入实用,鉴黄师的职业前景就面临着严重的威胁!ui
把一张照片转换为字符画,大体须要三步:编码
早年间以上步骤还须要专门作一个小软件来完成,而如今只须要简单的代码就能够直接在浏览器中实现。人工智能
由于字符画的本质是“字符”,能够用文本编辑器打开,对于计算机来讲,他们和其余的字符没有任何区别,“画”的性质只是由人类的想象力后天赋予的。因此,若是你用字符画的形式传播春宫图,仍是须要唐马儒。url
针对字符画生成的基础功能,Python已经内置了不少优秀的扩展库,能够在此基础上直接调用,而无需重复制造轮子。
图库PIL(Python Imaging Library)
基本的图像处理功能。
网库urllib
获取网络资源,以下载网上的图片。
from PIL import Image # 图像处理模块
from urllib import request #网络请求模块
复制代码
没有必要把0-255的灰度值一一对应为不一样的字符,通常十几个也就足够了。这里作以下定义:
ASCII_CHARS = [' ', '#', '?', '%', '.', '+', '.', '*', ':', ',', '@']
复制代码
这里将最低的灰度段映射为' '
(空格),也就是原图中空白或接近空白的部分,在字符画中也会会变成空白;而原图的黑点则变成@
。
读者朋友能够在后文的开放代码环境中想要定义本身的字符,并能够传入任意网络图片作实验。
4K屏已经逐渐普及,如今差很少的电脑显示器也能支持2K分辨率,若是把每一个像素点都变成一个字符,那出来的图片实在是太大了。
因此首先要对源图片进行压缩,再转换为灰度模式,即抛出色彩信息。
# 压缩图片
def scale_image(image, new_width=60):
(original_width, original_height) = image.size # 获取原图尺寸
aspect_ratio = original_height/float(original_width) * 0.5 # 计算高宽比,由于输出文本有2倍行距,因此乘0.5维持高宽比
new_height = int(aspect_ratio * new_width)
new_image = image.resize((new_width, new_height))
return new_image
# 灰度模式
def convert_to_grayscale(image):
return image.convert('L') # 调用image对象本身的.convert()方法
复制代码
而后是创建图片(压缩后)像素点到字符集的映射关系。
def map_pixels_to_ascii_chars(image, range_width=25):
# 将每一个像素根据其灰度值映射为一个字符,每一个字符对应25个灰度值
pixels_in_image = list(image.getdata()) # 获取原图灰度值列表
pixels_to_chars = [ASCII_CHARS[int(pixel_value/range_width)] for pixel_value in pixels_in_image]
# 对于每一个像素点,将其灰度值转换为列表ASCII_CHARS的索引
return "".join(pixels_to_chars)[/amalthea_sample_code]
复制代码
最后综合前面几个函数,以文本形式输出字符画。
def convert_image_to_ascii(image, new_width=60):
image = scale_image(image, new_width) # 调用scale_image()函数,压缩图片
image = convert_to_grayscale(image) # convert_to_grayscale()函数,转换为灰度图
pixels_to_chars = map_pixels_to_ascii_chars(image) # 映射至字符集
len_pixels_to_chars = len(pixels_to_chars) # 获取字符集长度
image_ascii = [pixels_to_chars[index: index + new_width] for index in range(0, len_pixels_to_chars, new_width)]
return "\n".join(image_ascii)
def handle_image_conversion(image_filepath, new_width=60):
image = Image.open(image_filepath) # Image.open()打开源图片
image_ascii = convert_image_to_ascii(image, new_width) # 调用上面的convert_image_to_ascii()函数
print(image_ascii) # 输出字符画
复制代码
接下来咱们能够将任意图片转换为字符画看看效果,为了充分发扬互联网精神,目前仅支持具备网络地址的图片(实际上是图片上传系统还没作好)。
下面来看一个实例,将一张QQ企鹅的图标转换为字符画,点击运行便可获得字符画。
from PIL import Image
ASCII_CHARS = [' ', '#', '?', '%', '.', '+', '.', '*', ':', ',', '@']
def scale_image(image, new_width=60):
"""Resizes an image preserving the aspect ratio. """
(original_width, original_height) = image.size
aspect_ratio = original_height/float(original_width) * 0.5
new_height = int(aspect_ratio * new_width)
new_image = image.resize((new_width, new_height))
return new_image
def convert_to_grayscale(image):
return image.convert('L')
def map_pixels_to_ascii_chars(image, range_width=25):
pixels_in_image = list(image.getdata())
pixels_to_chars = [ASCII_CHARS[int(pixel_value/range_width)] for pixel_value in
pixels_in_image]
return "".join(pixels_to_chars)
def convert_image_to_ascii(image, new_width=60):
image = scale_image(image, new_width)
image = convert_to_grayscale(image)
pixels_to_chars = map_pixels_to_ascii_chars(image)
len_pixels_to_chars = len(pixels_to_chars)
image_ascii = [pixels_to_chars[index: index + new_width] for index in
range(0, len_pixels_to_chars, new_width)]
return "\n".join(image_ascii)
def handle_image_conversion(image_filepath, new_width=60):
image = Image.open(image_filepath)
image_ascii = convert_image_to_ascii(image, new_width)
print(image_ascii)
from urllib import request
image_file_path = 'image2ascii.jpg' # 图片的本地名称
image_url = "http://upload.wikimedia.org/wikipedia/en/thumb/9/9c/Tencent_QQ.png/64px-Tencent_QQ.png" # 图片的网络地址
request.urlretrieve(image_url, image_file_path) # 将网络图片下载到本地,并重命名
handle_image_conversion(image_file_path) # 启动handle_image_conversion()这个总函数
复制代码
上节的例子仍然保留了默认的字符集和默认图像宽度60
,接下来的部分留给读者自由发挥,能够经过修改以下参数得到本身的字符画:
new_width
:字符画的尺寸(宽的字符数)ASCII_CHARS
:字符集image_url
:网络图片地址,就是你想要转换的图片当你在网上看到一张图片,右键-复制图片地址。
将图片地址赋值予变量image_url
,点击运行便可。
from PIL import Image
from urllib import request
def scale_image(image, new_width=60):
(original_width, original_height) = image.size
aspect_ratio = original_height/float(original_width) * 0.5
new_height = int(aspect_ratio * new_width)
new_image = image.resize((new_width, new_height))
return new_image
def convert_to_grayscale(image):
return image.convert('L')
def map_pixels_to_ascii_chars(image, range_width=25):
pixels_in_image = list(image.getdata())
pixels_to_chars = [ASCII_CHARS[int(pixel_value/range_width)] for pixel_value in
pixels_in_image]
return "".join(pixels_to_chars)
def convert_image_to_ascii(image, new_width=60):
image = scale_image(image, new_width)
image = convert_to_grayscale(image)
pixels_to_chars = map_pixels_to_ascii_chars(image)
len_pixels_to_chars = len(pixels_to_chars)
image_ascii = [pixels_to_chars[index: index + new_width] for index in
range(0, len_pixels_to_chars, new_width)]
return "\n".join(image_ascii)
def handle_image_conversion(image_filepath, new_width=60):
image = Image.open(image_filepath)
image_ascii = convert_image_to_ascii(image, new_width)
print(image_ascii)
image_file_path = 'image2ascii.jpg' # 图片的本地名称
new_width = 60 # 字符画宽几个字符
ASCII_CHARS = [' ', '#', '?', '%', '.', '+', '.', '*', ':', ',', '@'] # 字符集
image_url = "http://upload.wikimedia.org/wikipedia/en/thumb/9/9c/Tencent_QQ.png/64px-Tencent_QQ.png" # 图片的网络地址
request.urlretrieve(image_url, image_file_path)
handle_image_conversion(image_file_path, new_width)
复制代码
摘掉眼镜看效果更佳。