我用这种方法将一张普通的图片转换成ASCII艺术.但即使是在性能不强的处理器上处理小图像,也只会扼杀它们.有可能对此进行优化吗?我试着用麻木做一些东西,但我什么都没做.任何关于优化的帮助都将不胜感激,谢谢.以下是我失败的try (
算法摘自此处:https://github.com/Akascape/Ascify-Art
我的代码是:
from PIL import Image, ImageDraw, ImageFont
import math
def make_magic_old(photo, chars="01", char_size=15, char_width=10, char_height=18, scale=0.09):
# Rounding scale
scaleFactor = round(scale, 3)
# Calculate the length of the character list
charLength = len(list(chars))
# Calculate the interval for converting a pixel value into a character
interval = charLength / 256
# Convert the image to RGB
photo = photo.convert("RGB")
# Load font
fnt = ImageFont.truetype("assets/fonts/FiraCode-Bold.ttf", char_size)
# Get size of the image
width, height = photo.size
# Scaling the image
photo = photo.resize((int(scaleFactor * width), int(scaleFactor * height * (char_width / char_height))), Image.Resampling.NEAREST)
# Getting the sizes in a new way after scaling
width, height = photo.size
# Load pixels
pix = photo.load()
# Create a new image to display the result
outputImage = Image.new("RGB", (char_width * width, char_height * height), color="black")
# Create a drawing tool
draw = ImageDraw.Draw(outputImage)
# Replace pixes to text
for i in range(height):
for j in range(width):
r, g, b = pix[j, i]
# Calculate the average color value
h = int(r / 3 + g / 3 + b / 3)
# Convert pixel colors
pix[j, i] = (h, h, h)
# Display a symbol instead of a pixel
draw.text((j * char_width, i * char_height), chars[math.floor(h * interval)], font=fnt, fill=(r, g, b))
return outputImage
def main():
photo = Image.open("test.png")
result_photo = make_magic(photo)
result_photo.save("result.jpg")
print("Done!")
if __name__ == "__main__":
main()
try 用NumPy进行优化:
import numpy as np
def make_magic(photo, chars="01", char_size=15, char_width=10, char_height=18, scale=0.09):
# Rounding scale
scaleFactor = round(scale, 3)
# Calculate the length of the character list
charLength = len(chars)
# Convert the image to RGB and then to numpy array
photo = np.array(photo.convert("RGB"))
# Load font
fnt = ImageFont.truetype("assets/fonts/FiraCode-Bold.ttf", char_size)
# Get size of the image
height, width, _ = photo.shape
# Scaling the image
photo = np.array(Image.fromarray(photo).resize((int(scaleFactor * width), int(scaleFactor * height * (char_width / char_height))), Image.NEAREST))
# Getting the sizes in a new way after scaling
height, width, _ = photo.shape
# Convert the image to grayscale
grayscale_photo = np.mean(photo, axis=2).astype(np.uint8)
# Calculate indices for character selection
indices = (grayscale_photo * (charLength / 256)).astype(int)
# Create a new image to display the result
outputImage = Image.new("RGB", (char_width * width, char_height * height), color="black")
# Create a drawing tool
draw = ImageDraw.Draw(outputImage)
# Create character array
char_array = np.array(list(chars))
# Replace pixels with text
for i in range(height):
for j in range(width):
draw.text((j * char_width, i * char_height), char_array[indices[i, j]], font=fnt, fill=tuple(photo[i, j]))
return outputImage