图像转字符画

标签:
教育it |
字符画是一种由计算机键盘上的字符(即ASCII字符)组成的图画。例如一条鱼骨可表现为>++(>,一个微笑可表现为:)
多年前,常常见到网络上一些复杂的字符画,例如下图。
我一直很佩服字符画作者的创意,更感叹他们的耐心。竟可以用常用的或特殊的字符,细致调整缩进,从而设计出独特的作品。而今,发现原来字符画可以不用人工设计,而是用计算机编程设计。
现已很少在一些网站上看到字符画了,这是因为网络技术快速发展,网络带宽越来越大,容量更大的图片已可以在网络上快速传播,而且图片的存储与发布更为即时、方便。但是,字符画独特的视觉效果,依然有存在的意义。本文讨论采用Python编写程序,将图像转换成字符画。本例采用的图像是一张在新冠疫情中的逆行者照片,以此致敬医务人员始终坚守、不曾退却、无畏危险的精神。
一、字符转换的程序设计思路分析
本例的程序虽主要是调用库函数,但从培养学生计算思维的角度,有必要讲解和分析相关函数背后的算法。
程序设计的主要思路:使用程序将彩色图像转换为字符画时,先将采用彩色图像转换为灰度图像,然后把不同灰度等级的像素对应到不同明暗的ASCII字符。字符序列“MNHQ$OC?7>!:-;.”中各个字符的留白不同,因而它们能够呈现不同的明暗效果。
彩色图像常使用RGB色彩模式,通过对红、绿、蓝三种颜色通道的变化以及它们之间的叠加来表现丰富的颜色。灰度图像又称为黑白图像,使用0~255表示每个像素点的颜色深度,白色为255,黑色为0。彩色图像转换为灰度图像,可用下面的公式将图像中各个像素的RGB值转换为灰度值。
Gray=r*0.299+g*0.587+b*0.114
本例中使用Pillow图像处理库将彩色图像转换为灰度图像,其内部转换时使用的就是上述公式。
二、编程实践
语句 |
解释 |
from PIL import Image |
导入Pillow库的Image模块,Pillow库在Python 3中的名字为PIL。这里如果Python环境中未安装Pillow库,则需要先安装。 |
def main(): |
打开图片。其中Image.open()方法有于打开指定路径的图像文件,并返回一个图像对象。这里将一个医务工作者的照片nxz2-1.jpg放到当前程序文件所在目录。因而不需给出完整路径。 |
width, height = 300, 130 img = img. resize((width, height)) |
调整图像的尺寸。这里定义的字符画尺寸稍大,主要是为了可将字符画缩小,以便取得更佳的整体图像效果。 |
img = img. convert('L') |
转换为灰度图像。图像的convert()方法通过指定的参数转换图像的颜色模式。其中参数’L’表示灰度模式,’RGB’表示真彩色模式。 |
ascii_chars = list('MNHQ$OC?7>!:-;. ') def getchar(gray): |
这段代码的主要功能是由灰度值gray转换为相应的字符。 这里是抽象思维的关键。 定义了一个列表ascii_chars,该列表存放了16个表示明暗效果的字符。0~255表示了颜色深度。用n来表示应该应返回的列表ascii_chars中的字符位置,那么,n与灰度值gray的关系如下: gray/256=n/16 即n= gray/16 |
|
将图片每个像素的灰度值转换为一个字符,并存放到变量text中。 这里采用了双层循环结构。将图片先按的从左到右的顺序,即第一层循环for x in range(width),再按从上到下的顺序,即第二层循环for y in range(height),进行获取各个像素坐标,再由图像的getpixel()方法获取相应的灰度值。 图片各个像素坐标的获取是实现自动化的关键步骤,抽象到位,方可解决复杂问题。 这里对函数getchar()的调用,也体现了分解问题的思维方法。首先解决了一个灰度值返回一个字符的问题,然后,再解决逐个的灰度值获取字符的问题。 这两段代码是本例的精华,起到培养学生计算思维的关键。 |
|
将字符画保存到一个文本文件中,这里文本文件的名称为nxz2.txt |
编译程序后,在该程序所在的目录下将生成一个nxz2.txt的文本文件。由于先前考虑到了字符画的整体效果,设定的字符画高度、宽度都较大,因而可以借助浏览器打开文本文件,并缩小页面。如还需进一步缩小,则可以通过打印预览页面来查看整体效果。
本例整体效果如下图所示。
原图裁剪自下图。
其它字符画效果如下。
参考资料:
谢声涛.Python趣味编程:从入门到人工智能[M].清华大学出版社.