用 Python 制作 ASCII 字符画 您所在的位置:网站首页 python图片转彩色字符画 用 Python 制作 ASCII 字符画

用 Python 制作 ASCII 字符画

2023-10-29 05:48| 来源: 网络整理| 查看: 265

目录 1. 介绍 2. 准备工作 3. 生成黑白的 ASCII 字符画 3.1 第 1 步:调整图像大小并将其转换为灰度 3.2 第 2 步:将灰度像素映射到 ASCII 字符 3.3 第 3 步:将图像转换为 ASCII 字符画 3.4 第 4 步:存储 ASCII 字符画到文本文件 3.5 第 5 步:存储 ASCII 字符画到图像文件 3.6 效果展示 3.7 完整代码 4. 生成彩色的 ASCII 字符画 4.1 第 1 步:调整图像大小并将其转换为灰度 4.2 第 2 步:将图像转换为 ASCII 字符画 4.3 第 3 步:存储 ASCII 字符画到图像文件 4.4 效果展示 4.5 更多效果展示 4.6 完整代码 5. 总结 6. 附录 1. 介绍

ASCII 字符画 (ASCII Art) 是一种使用 ASCII 文本字符表示图像的创造性表达,可以追溯到图形界面受限的早期计算时代。 尽管技术在不断发展,但 ASCII 字符画经受住了时间的考验,在社交媒体平台、代码库和数字艺术社区中重新流行起来。 这篇文章将向您介绍使用 Python 生成 ASCII 字符画的方法和过程。

2. 准备工作

要使用 Python 制作 ASCII 艺术作品,您需要在计算机上设置 Python 环境。 如果您还没有,请从官方网站 (https://www.python.org/downloads/) 下载并安装 Python。 安装 Python 后,您需要安装 Pillow 库,用于打开、操作和保存图像文件:

要安装 Pillow 库,请打开终端或命令提示符并运行以下命令:

pip install pillow 3. 生成黑白的 ASCII 字符画

从图像创建 ASCII 艺术作品涉及几个基本步骤:调整图像大小、将其转换为灰度以及将灰度像素映射到 ASCII 字符。 在本节中,我们将使用 Python 和 Pillow 库完成这些步骤。

3.1 第 1 步:调整图像大小并将其转换为灰度

要使图像适合 ASCII 字符画,需要先将高分辨率图像调整为较小的分辨率,并将图像转换为灰度,因为 ASCII 字符画主要依靠灰色阴影来表示细节。

import PIL.Image as Image import PIL.ImageDraw as ImageDraw import PIL.ImageFont as ImageFont # 将图像调整为指定大小 def resize_image(image_path, output_width, output_height): # 打开图像 image = Image.open(image_path) # 调整图像大小 image = image.resize((output_width, output_height)) return image # 将图像转换为灰度图像 def convert_to_gray(image): return image.convert('L') 3.2 第 2 步:将灰度像素映射到 ASCII 字符

经过第1 步我们有了一个调整大小后的灰度图像,我们需要将每个像素的灰度值映射到一个 ASCII 字符。 为此,我们创建一串按视觉密度排序的 ASCII 字符,并将灰度值映射到这些字符。

# 将像素映射为 ASCII 字符 def map_pixels_to_ascii(gray_image, ascii_chars): ascii_image = [] # 遍历输出图像的每一行 for y in range(output_height): row = "" # 遍历输出图像的每一列 for x in range(output_width): # 获取当前像素的灰度值 gray_value = gray_image.getpixel((x, y)) # 根据灰度值计算对应的 ASCII 字符的索引 char_index = int(gray_value / 255 * (len(ascii_chars) - 1)) # 将对应的 ASCII 字符添加到当前行中 row += ascii_chars[char_index] # 将当前行添加到 ASCII 图像中 ascii_image.append(row) # 将 ASCII 字符画转换为字符串并返回 return "\n".join(ascii_image)

map_pixels_to_ascii 函数接受两个参数:

gray_image,输入的灰度图像。 ascii_chars,用于映射像素的 ASCII 字符集。ASCII 字符集的原则是按视觉密度排序,如@%#*+=-:.。 3.3 第 3 步:将图像转换为 ASCII 字符画

通过组织第1步、第2步中的函数我们可以将图像转换为 ASCII 字符画。其基本流程为:调整图像大小 → 转换为灰度图像 → 用 ASCII 字符替换像素。

# 将图像转换为黑白 ASCII 字符画 def image_to_bw_ascii(image_path, output_width, output_height): # 调整图片大小 resized_image = resize_image(image_path, output_width, output_height) # 转换为灰度图像 gray_image = convert_to_gray(resized_image) # 用 ASCII 字符替换像素 ascii_image = map_pixels_to_ascii(gray_image, bw_ascii_chars) return ascii_image

image_to_bw_ascii函数接收三个参数:

image_path,原始图片。可以是绝对路径,也可以是相对路径。 output_width,输出字符画的宽度。对于文本形式的字符画,如显示在终端窗口的字符画,其单位为列;对于图像形式的字符画,如存储在图片文件中的字符画,其单位为像素。 output_height,输出字符画的高度。对于文本形式的字符画,如显示在终端窗口的字符画,其单位为行;对于图像形式的字符画,如存储在图片文件中的字符画,其单位为像素。 3.4 第 4 步:存储 ASCII 字符画到文本文件

ASCII 字符画是由字符组成的,因此可以将其存储到文本文件中。

# 存储黑白 ASCII 字符画到文本文件 def save_bw_ascii_image_as_text(ascii_image, output_path): with open(output_path, 'w') as file: file.write(ascii_image)

save_bw_ascii_image_as_text函数接收三个参数:

ascii_image,ASCII 字符画。 output_path,存储 ASCII 字符画的文本文件。 3.5 第 5 步:存储 ASCII 字符画到图像文件

使用 Pillow 库可以将 ASCII 字符画存储为 jpg、png 等图片文件。

# 存储黑白 ASCII 字符画到图片 def save_bw_ascii_image_as_picture(ascii_image, font_path, font_size, output_path): # 将输入的 ASCII 字符画按换行符拆分 lines = ascii_image.split('\n') # 根据最长行的长度和行数计算出结果图像的宽度和高度 width = max(len(line) for line in lines) height = len(lines) # 使用计算出的尺寸和白色背景颜色创建一个新的 RGB 图像 image = Image.new('RGB', ((width * font_size), height * font_size), color='white') # 使用 ImageDraw.Draw 方法创建一个 Draw 对象 draw = ImageDraw.Draw(image) # 使用 ImageFont.truetype 方法创建一个 Font 对象 font = ImageFont.truetype(font_path, font_size) # 遍历 ASCII 艺术输入中的每个字符,并使用 Draw.text 方法将其绘制到图像上 for y, line in enumerate(lines): for x, char in enumerate(line): # 根据其 x 和 y 坐标以及 font_size 参数计算每个字符的位置 draw.text((x * font_size, y * font_size), char, font=font, fill='black') # 使用 Image.save 方法将生成的图像保存到 output_path 参数中 image.save(output_path)

save_bw_ascii_image_as_picture函数接收四个参数:

ascii_image,ASCII 字符画。 font_path,绘图所用字体。 font_size,绘图字体大小。 output_path,图片文件。 3.6 效果展示

把上面的步骤串联起来就可以将一幅图片转换为 ASCII 字符画,并将它输出到终端、保存到文本文件、保存到图片文件中。

# 定义输出宽度和高度(行/像素) output_width = 60 output_height = 35 # 定义黑白 ASCII 字符画绘图字体和字体大小 bw_ascii_image_font = "arial.ttf" bw_ascii_image_font_size = 8 # 定义黑白 ASCII 字符画替换像素的 ASCII 字符 bw_ascii_chars = "@%#*+=-:. " if __name__ == "__main__": image_path = "path/to/your/image.jpg" # 生成黑白 ASCII 字符画 bw_ascii_image = image_to_bw_ascii(image_path, output_width, output_height) # 输出到终端 print(bw_ascii_image) # 存储黑白 ASCII 字符画到文本文件 save_bw_ascii_image_as_text(bw_ascii_image, "bw_ascii_image.txt") # 存储黑白 ASCII 字符画到图片文件 save_bw_ascii_image_as_picture(bw_ascii_image, bw_ascii_image_font, bw_ascii_image_font_size, "bw_ascii_image.png")

注意将 "path/to/your/image.jpg" 替换为图像文件的路径。 您可以调整 output_width 和 output_height 变量来控制生成的 ASCII 字符画的大小。您还可以调整bw_ascii_chars变量来观察不同字符生成的 ASCII 字符画的效果。

下面是生成的 ASCII 字符画的效果示例。

原图:

终端输出效果:

生成的文本文件效果:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@###@@@@@@@@@@@@@@@@@@@@%####@@@@@@@@@@@@@@@ @@@@@@@@@@@@@##*######@@@@@@@@@@@@@@@@##*######@@@@@@@@@@@@@ @@@@@@@@@@@@@#+.:---*# @@@@@@@@@@@@@@ #+.::::*#@@@@@@@@@@@@@ @@@@@@@@@@@@@#*++***## @@@@@@@@@@@@@@ #*+++++*#@@@@@@@@@@@@@ @@@@@@@@@@@@@##+:::=##@@@@@@@@@@@@@@@@*##-:-###@@@@@@@@@@@@@ @@@@@@@@@@@@##= =##@@@@@@@@@@@@@ ###*. .*###@@@@@@@@@@@@ @@@@@@@@@@@##- -##@@@@@@@@@@@##*=:. .:=*##@@@@@@@@@@ @@@@@@@@@@##- .......-##@@@@@@@@@##=. .........=##@@@@@@@@@ @@@@@@@@@*#- .:.......=#*@@@@@@@*#: :::::::::::=#*@@@@@@@@ @@@@@@@@ #+. ...........*#:@@@@@-#+ .::::::::::::*# @@@@@@@ @@@@@@@@*#: .:.........-#*@@@@@+#= .::::::::::::+#-@@@@@@@ @@@@@@@@#*. ............:*#@@@@@+#= .::::::::::::+#-@@@@@@@ @@@@@@@ #+ .:...........+#:@@@@+#= .::::::::::::+#-@@@@@@@ @@@@@@@:#= .............=#+@@@@+#= .::::::::::::=#-@@@@@@@ @@@@@@@*#*+++++++++++++++*#*@@@@+#*+++*************#*@@@@@@@ @@@@@@@*#+::-============*#*@@@@+#+:::------------+#*@@@@@@@ @@@@@@@*#= .------------+#*@@@@+#= .::::::::::::+#*@@@@@@@ @@@@@@@*#= :--------====*#*@@@@+#= .::::::::----+#*@@@@@@@ @@@@@@@*#= :--------****##*@@@@+#= .:::::::-+**+##*@@@@@@@ @@@@@@@*#= :------------+#*@@@@+#= .::::::::::::+#*@@@@@@@ @@@@@@@*#= :------------+#*@@@@+#= .::::::::----+#*@@@@@@@ @@@@@@@*#= :--------****##*@@@@+#= .:::::::-****##*@@@@@@@ @@@@@@@*#= :------------+#*@@@@+#= .::::::::::::+#*@@@@@@@ @@@@@@@*#= .------------+#*@@@@+#= .::::::::::::+#*@@@@@@@ @@@@@@@*#*==+***********+*#*@@@@+#*==+++++++++++++*#*@@@@@@@ @@@@@@@=#+---------------+#*@@@@+#+---============+#-@@@@@@@ @@@@@@@-#- .............=#*@@@@+#= .::::::::::::=#-@@@@@@@ @@@@@@@-#= .:...........=#*@@@@+#= .::::::::::::+#-@@@@@@@ @@@@@@@-#= .:...........=#+@@@@+#= .::::::::::::+#:@@@@@@@ @@@@@@@ #*. ............:*# @@@@ #*. .::::::::::::*# @@@@@@@ @@@@@@@@*#*-..:::::::::-*#*@@@@@@*#*-..::::::::-=*#*@@@@@@@@ @@@@@@@@@@###*********###@@@@@@@@@@###********####@@@@@@@@@@ @@@@@@@@@@@@@*#######*@@@@@@@@@@@@@@@@@##******@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

生成的图片效果:

3.7 完整代码 # gen-bw-ascii-image.py import PIL.Image as Image import PIL.ImageDraw as ImageDraw import PIL.ImageFont as ImageFont # 定义输出宽度和高度(行/像素) output_width = 60 output_height = 35 # 定义黑白 ASCII 字符画绘图字体和字体大小 bw_ascii_image_font = "arial.ttf" bw_ascii_image_font_size = 8 # 定义黑白 ASCII 字符画替换像素的 ASCII 字符 bw_ascii_chars = "@%#*+=-:. " # 将图像调整为指定大小 def resize_image(image_path, output_width, output_height): image = Image.open(image_path) image = image.resize((output_width, output_height)) return image # 将图像转换为灰度图像 def convert_to_gray(image): return image.convert('L') # 将像素映射为 ASCII 字符 def map_pixels_to_ascii(gray_image, ascii_chars): ascii_image = [] for y in range(output_height): row = "" for x in range(output_width): gray_value = gray_image.getpixel((x, y)) char_index = int(gray_value / 255 * (len(ascii_chars) - 1)) row += ascii_chars[char_index] ascii_image.append(row) return "\n".join(ascii_image) # 将图像转换为黑白 ASCII 字符画 def image_to_bw_ascii(image_path, output_width, output_height): resized_image = resize_image(image_path, output_width, output_height) gray_image = convert_to_gray(resized_image) ascii_image = map_pixels_to_ascii(gray_image, bw_ascii_chars) return ascii_image # 存储黑白 ASCII 字符画到文本文件 def save_bw_ascii_image_as_text(ascii_image, output_path): with open(output_path, 'w') as file: file.write(ascii_image) # 存储黑白 ASCII 字符画到图片 def save_bw_ascii_image_as_picture(ascii_image, font_path, font_size, output_path): lines = ascii_image.split('\n') width = max(len(line) for line in lines) height = len(lines) image = Image.new('RGB', ((width * font_size), height * font_size), color='white') draw = ImageDraw.Draw(image) font = ImageFont.truetype(font_path, font_size) for y, line in enumerate(lines): for x, char in enumerate(line): draw.text((x * font_size, y * font_size-), char, font=font, fill='black') image.save(output_path) if __name__ == "__main__": image_path = "path/to/your/image.jpg" # 生成黑白 ASCII 字符画 bw_ascii_image = image_to_bw_ascii(image_path, output_width, output_height) # 存储黑白 ASCII 字符画到文本文件 save_bw_ascii_image_as_text(bw_ascii_image, "bw_ascii_image.txt") # 存储黑白 ASCII 字符画到图片文件 save_bw_ascii_image_as_picture(bw_ascii_image, bw_ascii_image_font, bw_ascii_image_font_size, "bw_ascii_image.png") # 在终端窗口打印彩色 ASCII 字符画 print(bw_ascii_image) 4. 生成彩色的 ASCII 字符画

在色彩斑斓的现代社会 ASCII 字符画也要进步,下面我们探索如何生成彩色的 ASCII 字符画。

生成彩色 ASCII 字符画的步骤与生成黑白 ASCII 字符画的步骤基本相同,详述如下。

4.1 第 1 步:调整图像大小并将其转换为灰度

此步骤与生成黑白 ASCII 字符画的第 1 步相同,此处略过。

4.2 第 2 步:将图像转换为 ASCII 字符画

对于彩色字符画我们需要逐个像素地扫描图像,提取像素颜色,并完成像素到字符的映射,同时将扫描的信息存储起来,从而实现将图像转换为彩色的 ASCII 字符画。

# 将图像转换为彩色 ASCII 字符画 def image_to_colored_ascii(image_path, output_width, output_height): # 调整图片大小 resized_image = resize_image(image_path, output_width, output_height) # 创建 ASCII 字符画 ascii_image = [] ascii_image_chars = [] ascii_image_colors=[] for y in range(output_height): row = "" for x in range(output_width): # 获取像素颜色 color = resized_image.getpixel((x, y)) # 计算灰度值并选择相应的 ASCII 字符 gray_value = sum(color) // 3 char_index = int(gray_value / 255 * (len(colored_ascii_chars) - 1)) if char_index >= len(colored_ascii_chars): char_index = len(colored_ascii_chars) - 1 # 将 ASCII 字符和颜色添加到行中 row += f"\033[38;2;{color[0]};{color[1]};{color[2]}m{colored_ascii_chars[char_index]}" # 存储字符和颜色 ascii_image_chars.append(colored_ascii_chars[char_index]) ascii_image_colors.append((color[0], color[1], color[2])) # 将行添加到 ASCII 字符画中 ascii_image.append(row) return "\n".join(ascii_image), ascii_image_chars, ascii_image_colors 4.3 第 3 步:存储 ASCII 字符画到图像文件

下面的函数是将彩色 ASCII 字符画存储为图片。它通过创建一个新的 RGB 图像来实现,该图像的尺寸为 output_width * font_size和 output_height * font_size。然后使用 ImageDraw 模块将 ASCII 字符以及相应的颜色绘制到图像上。最后,将图像保存到指定的 output_path。

# 将彩色 ASCII 艺术图像存储为图片 def save_colored_ascii_image_as_picture(ascii_image_chars, ascii_image_colors, font_path, font_size, output_path): # 创建一个新的 RGB 图像 image = Image.new('RGB', ((output_width * (font_size-3)), (output_height * (font_size-1))), color='black') draw = ImageDraw.Draw(image) font = ImageFont.truetype(font_path, font_size) # 绘制 ASCII 字符和颜色 for i in range(output_height): for j in range(output_width): draw.text((j * (font_size-3), i * (font_size-1)), ascii_image_chars[i*output_width+j], font=font, fill=ascii_image_colors[i*output_width+j]) # 保存图像 image.save(output_path) 4.4 效果展示

将上面的代码组织一下就可以实现我们的目标了:将一幅图片转换为彩色 ASCII 字符画,并将它输出到终端、保存到图片文件中。

# 定义输出宽度和高度(行/像素) output_width = 60 output_height = 35 # 定义彩色 ASCII 字符画绘图字体和字体大小 colored_ascii_image_font = "arial.ttf" colored_ascii_image_font_size = 8 # 定义彩色 ASCII 字符画替换像素的 ASCII 字符 colored_ascii_chars = ["0", "1", "2", "3", "4", "5", "6", "8", "9"] if __name__ == "__main__": image_path = "path/to/your/image.jpg" # 将图像转换为彩色 ASCII 字符画 colored_ascii_image, colored_ascii_image_chars, colored_ascii_image_colors = image_to_colored_ascii(image_path, output_width, output_height) # 存储彩色 ASCII 字符画到图片文件 save_colored_ascii_image_as_picture(colored_ascii_image_chars, colored_ascii_image_colors, colored_ascii_image_font, colored_ascii_image_font_size, "colored_ascii_image.png") # 在终端窗口打印彩色 ASCII 字符画 print(colored_ascii_image)

注意将 "path/to/your/image.jpg" 替换为图像文件的路径。

下面是生成的彩色 ASCII 字符画的效果示例。

终端输出效果:

生成的图片效果:

4.5 更多效果展示

4.6 完整代码 # gen-colored-ascii-image.py import PIL.Image as Image import PIL.ImageDraw as ImageDraw import PIL.ImageFont as ImageFont # 定义输出宽度和高度(行/像素) output_width = 60 output_height = 35 # 定义彩色 ASCII 字符画绘图字体和字体大小 colored_ascii_image_font = "arialbd.ttf" colored_ascii_image_font_size = 8 # 定义彩色 ASCII 字符画替换像素的 ASCII 字符 colored_ascii_chars = ["0", "1", "2", "3", "4", "5", "6", "8", "9"] # 将图像调整为指定大小 def resize_image(image_path, output_width, output_height): image = Image.open(image_path) image = image.resize((output_width, output_height)) return image # 将图像转换为灰度图像 def convert_to_gray(image): return image.convert('L') # 将图像转换为彩色 ASCII 字符画 def image_to_colored_ascii(image_path, output_width, output_height): resized_image = resize_image(image_path, output_width, output_height) ascii_image = [] ascii_image_chars = [] ascii_image_colors=[] for y in range(output_height): row = "" for x in range(output_width): color = resized_image.getpixel((x, y)) gray_value = sum(color) // 3 char_index = int(gray_value / 255 * (len(colored_ascii_chars) - 1)) if char_index >= len(colored_ascii_chars): char_index = len(colored_ascii_chars) - 1 row += f"\033[38;2;{color[0]};{color[1]};{color[2]}m{colored_ascii_chars[char_index]}" ascii_image_chars.append(colored_ascii_chars[char_index]) ascii_image_colors.append((color[0], color[1], color[2])) ascii_image.append(row) return "\n".join(ascii_image), ascii_image_chars, ascii_image_colors # 将彩色 ASCII 艺术图像存储为图片 def save_colored_ascii_image_as_picture(ascii_image_chars, ascii_image_colors, font_path, font_size, output_path): image = Image.new('RGB', ((output_width * font_size), (output_height * font_size)), color='black') draw = ImageDraw.Draw(image) font = ImageFont.truetype(font_path, font_size) for i in range(output_height): for j in range(output_width): draw.text((j * font_size, i * font_size), ascii_image_chars[i*output_width+j], font=font, fill=ascii_image_colors[i*output_width+j]) image.save(output_path) if __name__ == "__main__": image_path = "path/to/your/image.jpg" # 将图像转换为彩色 ASCII 字符画 colored_ascii_image, colored_ascii_image_chars, colored_ascii_image_colors = image_to_colored_ascii(image_path, output_width, output_height) # 存储彩色 ASCII 字符画到图片文件 save_colored_ascii_image_as_picture(colored_ascii_image_chars, colored_ascii_image_colors, colored_ascii_image_font, colored_ascii_image_font_size, "colored_ascii_image.png") # 在终端窗口打印彩色 ASCII 字符画 print(colored_ascii_image) 5. 总结

本文向您介绍了 ASCII 字符画的迷人世界,并展示了 Python 如何成为制作您自己的字符画杰作的强大工具。 您可以尝试不同的图像、不同的设置来创建独特且令人着迷的 ASCII 艺术作品。您还可以在本文的基础上继续探索,创造更多有趣的功能。

6. 附录

以下是一些与 ASCII 字符画相关的资源,您可以在其中找到创建 ASCII 艺术的示例和灵感:

ASCII Art Archive:大量的 ASCII 艺术收藏。 ASCII World:一个以各种 ASCII 艺术示例和资源为特色的网站。 相关博客文章 Python 中的浅拷贝和深拷贝 Python 字典 (Dictionary) 入门 从串联到 F-字符串:释放 Python 字符串格式化的力量 神奇的 Python 元类 (metaclass) 及其应用 Python 之禅 使用 Python 生成 Lorem lpsum 拉丁文本 有趣的 Python - 石头、剪刀、布 如何在 Python 中解包可迭代对象 如何测试 Python 代码的速度 - datetime, timeit 免安装体验 Python 3.8 新特性 相关书籍教程文章 《Python 代码片段集锦》- 检查是否包含指定字符串 《Python 代码片段集锦》- 格式化字符串 《Python 代码片段集锦》- 检查文件是否存在 《Python 代码片段集锦》- 统计元素在列表中出现的次数 《Python 代码片段集锦》- 移除列表中的重复项 《Python 代码片段集锦》- 获取列表的最后一个元素 《Python 代码片段集锦》- 检查列表是否为空 《Python 代码片段集锦》- 给列表添加新项 《Python 代码片段集锦》- 前言 官方公众号

💯本站文章同步发表在官方公众号 ReadingHere,关注公众号您将在第一时间了解本站最新文章和资讯。

❤️欢迎您关注本站官方公众号 ReadingHere

版权声明

本文由ReadingHere原创,未经ReadingHere授权不得转载、摘编。已经授权使用的,应在授权范围内使用,并注明来源: www.readinghere.com。违反上述声明者,ReadingHere将追究其相关法律责任。

交流合作

如需交流咨询或商务合作请扫描下图微信二维码联系。

~~~ 探索更多文章 ~~~ Java Visual Studio Code PowerPoint Word CSS .NET python Markdown reStructuredText Obsidian 思维导图 知识图谱 PS Obsidian插件 lorem


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有