通过 Python 把图片转换为 ASCII art,好玩!
作者 |周萝卜
来源 |萝卜大杂烩

image 的本质
将 pixels 转换为 ASCCII
# Import types for clarity
from typing import NewType, Tuple
# Maximum value the sum of the pixel's channel values can reach
MAX_CHANNEL_VALUES = 255 * 4
# Defining an RGBA pixel type as a tuple of 4 integers
Pixel = NewType("Pixel", Tuple[int, int, int, int])
# Returns the pixel's intensity value as a float
def get_pixel_intensity(pixel: Pixel) -> float:
# Sum of the pixel's channel values divided by the maximum possible intensity
return sum(pixel) / MAX_CHANNEL_VALUES
为了清晰起见,我们在第一行导入了静态类型
# Character set for out ASCII arts
CHARACTERS = (' ', '.', '°', '*', 'o', 'O', '#', '@')
# Restuns the character that corresponds to the given pixel intensity
def map_intensity_to_character(intensity: float) -> CHARACTERS:
return CHARACTERS[round(intensity * len(CHARACTERS))]
# Import an image library for the sake of simplicity
from PIL import Image
# Import argv for command line arguments
from sys import argv
# Transforms an image into a string of ASCII characters
def convert_image(image: Image) -> str:
ascii_string = ''
# Iterate over every pixel of the image
for pixel in image.getdata():
intensity = get_pixel_intensity(pixel)
character = map_intensity_to_character(intensity)
ascii_string += character
return ascii_string
def main():
# Get the image name from the command line arguments list
image_name = argv[1]
# Open the image file using the PIL image library
image = Image.open(image_name)
# Convert the image to a string of ASCII characters
ascii_image = convert_image(image)
if __name__ == '__main__':
main()
查看 ASCII
# Prints the given ASCII art
# size is a Tuple containing the width and height of the image
def print_ascii_art(size: Tuple[int, int], characters: str):
index = 0
# Iterate over all the rows of the image
for _ in range(size[1]):
# Print a number of characters equal to the width of the image
# from the ascii string
print(characters[index:index+size[0]])
index += size[0]
def main():
image_name = argv[1]
image = Image.open(image_name)
ascii_image = convert_image(image)
# Actually print the ASCII image to the console
print_ascii_art(image.size, ascii_image)

python converter.py image.png

# The starting point of the generated HTML file
HTML_TEMPLATE = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ASCII Art</title>
</head>
<body>
<div style="background-color: black; color: white;">
<pre>{}</pre>
</div>
</body>
</html>
"""
def ascii_image_to_html(image_name: str, characters: str, size: Tuple[int, int]):
# Open an HTML file for writing with the '.html' extension
with open(image_name + '.html', 'w') as image_file:
ascii_image = ''
index = 0
# Generate the ASCII image as explained before
for _ in range(size[1]):
# Manually add a newline character at the end of each row or characters
ascii_image += characters[index:index+size[0]] + '\n'
index += size[0]
# Finally write the ASCII string to the HTML file using the template
image_file.write(HTML_TEMPLATE.format(ascii_image))
def main():
image_name = argv[1]
image = Image.open(image_name)
ascii_image = convert_image(image)
# Save the result in an HTML file
ascii_image_to_html(image_name, ascii_image, image.size)






#!/usr/bin/env python3
from typing import Tuple, NewType
from PIL import Image
from sys import argv
Pixel = NewType("Pixel", Tuple[int, int, int, int])
CHARACTERS = (' ', '.', '°', '*', 'o', 'O', '#', '@')
MAX_CHANNEL_INTENSITY = 255
MAX_CHANNEL_VALUES = MAX_CHANNEL_INTENSITY * 4 # 4 is the number of channels of a Pixel
HTML_TEMPLATE = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ASCII Art</title>
</head>
<body>
<div style="background-color: black; color: white; line-height: 10px">
<pre>{}</pre>
</div>
</body>
</html>
"""
def map_intensity_to_character(intensity: float) -> CHARACTERS:
return CHARACTERS[round(intensity * len(CHARACTERS))]
def get_pixel_intensity(pixel: Pixel) -> float:
return sum(pixel) / 1020 # 1020 = 255 * 4
def print_ascii_art(size: Tuple[int, int], characters: str):
index = 0
for _ in range(size[1]):
print(characters[index:index+size[0]])
index += size[0]
def ascii_image_to_html(image_name: str, characters: str, size: Tuple[int, int]):
with open(image_name + '.html', 'w') as image_file:
ascii_image = ''
index = 0
for _ in range(size[1]):
ascii_image += characters[index:index+size[0]] + '\n'
index += size[0]
image_file.write(HTML_TEMPLATE.format(ascii_image))
def convert_image(image: Image) -> str:
ascii_string = ''
for pixel in image.getdata():
intensity = get_pixel_intensity(pixel)
character = map_intensity_to_character(intensity)
ascii_string += character
return ascii_string
def main() -> None:
image_name = argv[1]
image = Image.open(image_name)
print(image.size, image.mode, image.size, image.getcolors())
ascii_image = convert_image(image)
#print_ascii_art(image.size, ascii_image)
ascii_image_to_html(image_name, ascii_image, image.size)
if __name__ == '__main__':
main()
原文地址:https://towardsdatascience.com/convert-pictures-to-ascii-art-ece89582d65b


分享

点收藏

点点赞

点在看
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

随时掌握互联网精彩
赞助链接
排名
热点
搜索指数
- 1 铁肩担道义 历史鉴未来 7904461
- 2 中方对会谈结果满意吗?外交部回应 7809090
- 3 英国首相斯塔默住所起火 7712095
- 4 中国经济必将破浪前行 7617620
- 5 中美双方降低超100%关税 7521679
- 6 40℃高温要来了 7425741
- 7 利用工作之便出售公民个人信息?罚 7327594
- 8 汶川地震67只搜救犬已全部离世 7233324
- 9 黄晓明金世佳进博士复试 7141746
- 10 中美各取消91%关税 暂停24%关税 7046934