加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

图像转字符画

(2020-03-27 20:15:32)
标签:

教育

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():

    img_name = 'nxz2-1.jpg'

    img= Image.open(img_name)

打开图片。其中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):

    n = gray / /16

    return ascii_chars[int(n)]

这段代码的主要功能是由灰度值gray转换为相应的字符。

这里是抽象思维的关键。

定义了一个列表ascii_chars,该列表存放了16个表示明暗效果的字符。0~255表示了颜色深度。用n来表示应该应返回的列表ascii_chars中的字符位置,那么,n与灰度值gray的关系如下:

gray/256=n/16

n= gray/16

 

    text = ''

    for y in range(height):

        for x in range(width):

            text += getchar(img.getpixel((x, y)))

        text += '\n'

将图片每个像素的灰度值转换为一个字符,并存放到变量text中。

这里采用了双层循环结构。将图片先按的从左到右的顺序,即第一层循环for x in range(width),再按从上到下的顺序,即第二层循环for y in range(height),进行获取各个像素坐标,再由图像的getpixel()方法获取相应的灰度值。

图片各个像素坐标的获取是实现自动化的关键步骤,抽象到位,方可解决复杂问题。

这里对函数getchar()的调用,也体现了分解问题的思维方法。首先解决了一个灰度值返回一个字符的问题,然后,再解决逐个的灰度值获取字符的问题。

这两段代码是本例的精华,起到培养学生计算思维的关键。

    fo = open('nxz2.txt', 'w')

    fo.write(text)

    fo.close()

将字符画保存到一个文本文件中,这里文本文件的名称为nxz2.txt

编译程序后,在该程序所在的目录下将生成一个nxz2.txt的文本文件。由于先前考虑到了字符画的整体效果,设定的字符画高度、宽度都较大,因而可以借助浏览器打开文本文件,并缩小页面。如还需进一步缩小,则可以通过打印预览页面来查看整体效果。

本例整体效果如下图所示。

图像转字符画


原图裁剪自下图。

图像转字符画

 

其它字符画效果如下。

图像转字符画

图像转字符画

 

参考资料:

谢声涛.Python趣味编程:从入门到人工智能[M].清华大学出版社.


0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有