Introduction
Recently I found a fun way to play Python, using Python to convert pictures into ASCII image, most of which are local programs, because I built an online version of Python before, so I tried to use the online version of Python to realize image-to-ASCII.
Online Python editor: https://lwebapp.com/en/python-playground
Analysis
The basic idea of image-to-ASCII painting is
- Use PIL to get the RGB color value of each pixel of the image
- Then map the RGB color value to a string
- Finally, just splicing the strings together, printing to the terminal or saving as text, you can see the ASCII image.
We are here for the convenience of demonstration, and use the print
method to print characters uniformly.
Code
Since we want to present on a web page, we can't load the image locally, we choose to load the image directly from base64 encoding, or load it from a remote URL. Here we will introduce how to load images.
1. Use base64 images
Use regular expressions to remove the header information of the picture base64 encoded string, and then use the base64
method to decode, and BytesIO
cooperates with PIL
to open it as a PIL picture instance.
Here I recommend my Online Image to Base64 tool, which supports directly pasting images and converting them into base64 strings, which is very convenient
import base64
import re
from io import BytesIO
from PIL import Image
# random string
char = list('M3NB6Q#OC?7>!:–;. ')
# color value map string
def get_char(r, g, b, alpha=256):
if alpha == 0:
return ' '
grey = (2126 * r + 7152 * g + 722 * b) / 10000
char_idx = int((grey / (alpha + 1.0)) * len(char))
return char[char_idx]
# image base64 string
img_base64 = '''data:image/png;base64,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'''
# Regularly delete header information, that is, Data URI scheme
image_data = re.sub('^data:image/.+;base64,', '', img_base64)
# open image
img = Image.open(BytesIO(base64.b64decode(image_data)))
img_widht = img.size[0]
img_height = img.size[1]
# set zoom ratio
scale_width = 0.3 # 0.75
scale_height = 0.1 # 0.5
# zoom image
img = img.resize((int(img_widht*scale_width),
int(img_height*scale_height)), Image.NEAREST)
# output ASCII image
text = ''
for i in range(int(img_height*scale_height)):
for j in range(int(img_widht*scale_width)):
text += get_char(*img.getpixel((j, i)))
text += '\n'
print(text)
Save the above code locally or copy it to Online Python Editor and run it to see the effect (Pillow needs to be installed before running)
2. Load image from URL
If it is a local application, we can use requests
, a built-in Python library, to load network images. Since this online Python tool uses pyodide and does not support requests, we need to use the official API pyodide.http.pyfetch
to implement the network ask
response = await pyodide.http.pyfetch('https://gcore.jsdelivr.net/gh/openHacking/static-files@main/img/16576149784751657614977527.png')
After getting the image data, you can also open it with PIL. The detailed code is as follows
from io import BytesIO
from PIL import Image
import pyodide
char = list('M3NB6Q#OC?7>!:–;. ')
def get_char(r, g, b, alpha=256):
if alpha == 0:
return ' '
grey = (2126 * r + 7152 * g + 722 * b) / 10000
char_idx = int((grey / (alpha + 1.0)) * len(char))
return char[char_idx]
def write_file(out_file_name, content):
with open(out_file_name, 'w') as f:
f.write(content)
# Python API provided by pyodide for network requests, reference: https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.pyfetch
response = await pyodide.http.pyfetch('https://gcore.jsdelivr.net/gh/openHacking/static-files@main/img/16576149784751657614977527.png')
image_data = await response.bytes()
img = Image.open(BytesIO(image_data))
img_widht = img.size[0]
img_height = img.size[1]
scale_width = 0.3 # 0.75
scale_height = 0.1 # 0.5
img = img.resize((int(img_widht*scale_width),
int(img_height*scale_height)), Image.NEAREST)
text = ''
for i in range(int(img_height*scale_height)):
for j in range(int(img_widht*scale_width)):
text += get_char(*img.getpixel((j, i)))
text += '\n'
print(text)
Online Demo: Python Image to ASCII - URL Image
Conclusion
The above is my summary of the method of converting image to ASCII in Python, which can be run on web pages and shared with your friends. There may be some shortcomings, welcome to explore. There will be more interesting Python usages in the future, welcome to follow my updates.
Top comments (0)