春节创意投稿·使用Python将虎年庆贺图像转为字符画

“ PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛

春节创意投稿·使用Python将虎年庆贺图像转为字符画

1. 展示效果

pic1.jpg

pic2.png

2. 步骤拆分

2.1 编写图像转字符画

将一副图像转化为字符画,其重点在于如何理解图像的像素点颜色与字符的关系。通常来讲,我们一般以像素点颜色较的颜色用书写较为简单的字符表示,而颜色较的颜色用书写较为复杂的字符表示。

在此,我们先定义一个字符串列表,从左至右分别表示像素点颜色由深到浅所要对应的字符。

charList = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789&%/|(){}[]?-_+~<>!;:,^`'.*-\”\’")
复制代码

其次,我们要如何来判定像素点的颜色是深亦或是浅呢?任何颜色都是由3种颜色组成,即红色、绿色以及蓝色,其各自的取值范围一般都在0到255之间。当红色、绿色以及蓝色的取值都一样时,我们则称其为灰度图,即只有黑白两种颜色的图,由于红色、绿色以及蓝色的取值都一样,其值常被统称为灰度值。灰度值越低,表示颜色越浅。灰度值越高,表示颜色越深。

在不同领域,通过某个像素点的颜色并获得其灰度值有不同公式,在此我们用以下公式计算:

灰度值 = R 0.3 + G 0.6 + B 0.1 灰度值 = R * 0.3 + G * 0.6 + B * 0.1
# 将像素点转换为字符列表中对应的字符
def getCharFromColor(color):
    r, g, b = color
    gray = 0.30 * r + 0.6 * g + 0.1 * b
    perCharOccurNum = (round)(255 / len(charList))
    index = (int)(gray / perCharOccurNum)
    return charList[index]
复制代码

2.2 编写图像转字符画

将图像转化为字符画,只需要获取图像的每一个像素点,并将每一个像素点转化为对应的字符,逐个添加到文本文件之中即可。

# 将图像转换为文本文件
# imagePath 图像路径
def changeImageToChar(imagePath):
    image = Image.open(imagePath)
    width, height = image.size
    result = ""
    for i in range(0, width):
        for j in range(0, height):
            r, g, b = image.getpixel((i, j))
            result += getCharFromColor((r, g, b))
        result += "\n"
    with open("image.txt", 'w') as file:
        file.write(result)
复制代码

2.3 编写字符画转图像

编写字符画转为图像的时,要注意图像的宽度以及高度,在这里,我们将图像的宽度以及高度分别设置为文本的每行字符数的N倍以及为文本行数的N倍。之所以设置为N倍,是因为避免往图像写入字符时,若图像的宽度以及高度文本每行的字符数以及总行数,而这会使得一个像素对应一个字符,而这样是由于留给字符的空间过小,所以会使得最终生成的字符不能正常地在图像上显示出来。因此我们要扩大图像的宽度以及高度。

# 将字符画转化为图像
def changeTxtToImage(txtPath):
    file = open(txtPath)
    line = file.readline()
    height = 1
    width = len(line)  # 获取文本每行的字符数
    # 获取文本行数
    while line:
        height += 1
        line = file.readline()
    image = Image.new('RGB', (width * 10, height * 10), (255, 255, 255))  # 创建图像等待字符进行填充
    file.close()
    startIndex = 0
    file = open(txtPath)
    line = file.readline()
    draw = ImageDraw.Draw(image)
    while line:
        for i in range(0, len(line)):
            draw.text((startIndex * 10 , i * 10), line[i], fill=(0, 0, 0)) # 为图像添加字符
        line = file.readline()
        startIndex += 1
    file.close()
    image.save('result.jpg')
复制代码

3. 完整代码

from PIL import Image, ImageDraw, ImageFont

# 定义字符,字符与图像的某个像素点的颜色对应
charList = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789&%/|(){}[]?-_+~<>!;:,^`'.*-\”\’")


# 将颜色转换为对应的字符
# color 像素点颜色
def getCharFromColor(color):
    r, g, b = color
    gray = 0.30 * r + 0.6 * g + 0.1 * b
    perCharOccurNum = (round)(255 / len(charList))
    index = (int)(gray / perCharOccurNum)
    return charList[index]


# 将图像转换为字符画
# imagePath 图像路径
def changeImageToChar(imagePath):
    image = Image.open(imagePath)
    width, height = image.size
    result = ""
    for i in range(0, width):
        for j in range(0, height):
            r, g, b = image.getpixel((i, j))
            result += getCharFromColor((r, g, b))
        result += "\n"
    with open("image.txt", 'w') as file:
        file.write(result)


# 将字符画转换为图像
# txtPath 字符画路径
def changeTxtToImage(txtPath):
    file = open(txtPath)
    line = file.readline()
    height = 1
    width = len(line)  # 获取文本每行的字符数
    # 获取文本行数
    while line:
        height += 1
        line = file.readline()
    image = Image.new('RGB', (width * 10, height * 10), (255, 255, 255))  # 创建图像等待字符进行填充
    file.close()
    startIndex = 0
    file = open(txtPath)
    line = file.readline()
    draw = ImageDraw.Draw(image)
    while line:
        for i in range(0, len(line)):
            draw.text((startIndex * 10, i * 10), line[i], fill=(0, 0, 0)) #  为图像添加字符
        line = file.readline()
        startIndex += 1
    file.close()
    image.save('result.jpg')


if __name__ == '__main__':
    changeImageToChar('image.jpg')
    changeTxtToImage('image.txt')
复制代码

作者:通雄

版权声明:本文为原创文章,未经本人允许不得转载。

Supongo que te gusta

Origin juejin.im/post/7061145936621207583
Recomendado
Clasificación