当前位置:   article > 正文

python学习之手把手教你将图片变成黑白或彩色字符画(骚操作)_python黑白图片上色公式

python黑白图片上色公式


前言

字符画这个话题,似乎早在贴吧时代就已经被玩烂了。在百度图片随便一搜索,就能够看到非常多。然后在这个时代,会编程的人越来越多(尤其是 MATLAB,Python 等非常适合图像处理的脚本语言),类似的教程更是数不胜数。
在这里插入图片描述


一、字符画的实现原理

字符画是一系列字符的组合,我们可以把字符看作是比较大块的像素,一个字符能表现一种颜色(暂且这么理解吧),字符的种类越多,可以表现的颜色也越多,图片也会更有层次感。

问题来了,我们是要转换一张彩色的图片,这么多的颜色,要怎么对应到单色的字符画上去?这里就要介绍灰度值的概念了。

灰度值:指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0,故黑白图片也称灰度图像
我们可以使用灰度值公式将像素的 RGB 值映射到灰度值:

gray = 0.2126 * r + 0.7152 * g + 0.0722 * b

这样就好办了,我们可以创建一个不重复的字符列表,灰度值小(暗)的用列表开头的符号,灰度值大(亮)的用列表末尾的符号。
在这里插入图片描述
在这里插入图片描述

二、黑白字符画实现代码

demo.py test.jpg -o outfile.txt --width 90 --height 90

代码如下(示例):

from PIL import Image
import argparse

def get_char(r,g,b,a=256):
    if a == 0:
        return ' '
    gray = 0.2126 * r + 0.7152 * g + 0.0722 * b
    length = len(ascii_str)
    unit = 256/length
    return ascii_str[int(gray/unit)]

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('file')  # 需要设置输入文件
    parser.add_argument('-o', '--output')  # 输出文件
    parser.add_argument('--width', type=int, default=80)  # 输出字符画宽
    parser.add_argument('--height', type=int, default=80)  # 输出字符画高

    # 获取参数
    args = parser.parse_args()
    IMG = args.file
    WIDTH = args.width
    HEIGHT = args.height
    OUTPUT = args.output

    ascii_str = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
    im = Image.open(IMG)
    im = im.resize((WIDTH,HEIGHT))
    txt = ''
    for i in range(HEIGHT):
        for j in range(WIDTH):
            txt += get_char(*im.getpixel((j,i))) # (r,g,b,a)
        txt += '\n'

    print(txt)
    #字符画输出到文件
    if OUTPUT:
        with open(OUTPUT,'w') as f:
            f.write(txt)
    else:
        with open("output.txt",'w') as f:
            f.write(txt)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

三、彩色字符画生成

在这里插入图片描述

代码实现:

import numpy as np
import cv2
from PIL import Image, ImageFont, ImageDraw, ImageFilter
import random
from pathlib import Path
import time
from tqdm import tqdm

def color(
    input: str,
    output: str = None,
    rows: int = 100,
    alphabet='uppercase',
    background='origin7',
    out_height: int = None,
    scale: float = None,
):
    """output colorful text picture"""
    input_path = Path(input)
    # the original image
    origin = Image.open(input_path)
    width, height = origin.size
    print(f'input size: {origin.size}')
    # text amount of the output image
    text_rows = rows
    text_cols = round(width / (height / text_rows) * 1.25)  # char height-width ratio
    origin_ref_np = cv2.resize(
        np.array(origin), (text_cols, text_rows), interpolation=cv2.INTER_AREA
    )
    origin_ref = Image.fromarray(origin_ref_np)
    # font properties
    fontsize = 17
    font = ImageFont.truetype('courbd.ttf', fontsize)
    char_width = 8.88
    char_height = 11
    # output size depend on the rows and cols
    canvas_height = round(text_rows * char_height)
    canvas_width = round(text_cols * char_width)
    # a canvas used to draw texts on it
    canvas = get_background(background, origin, canvas_width, canvas_height)
    print(f'canvas size: {canvas.size}')
    # start drawing
    since = time.time()
    print(f'Start transforming {input_path.name}')
    draw = ImageDraw.Draw(canvas)
    charlist = get_alphabet(alphabet)
    length = len(charlist)

    for i in tqdm(range(text_cols)):
        for j in range(text_rows):
            x = round(char_width * i)
            y = round(char_height * j - 4)
            char = charlist[random.randint(0, length - 1)]
            color = origin_ref.getpixel((i, j))
            draw.text((x, y), char, fill=color, font=font)
    # resize the reproduct if necessary
    if out_height:  # height goes first
        canvas_height = out_height
        canvas_width = round(width * canvas_height / height)
        canvas = canvas.resize((canvas_width, canvas_height), Image.BICUBIC)
    elif scale:
        canvas_width = round(width * scale)
        canvas_height = round(height * scale)
        canvas = canvas.resize((canvas_width, canvas_height), Image.BICUBIC)
    # output filename
    if output:
        output_path = Path(output)
    else:
        output_path = input_path.with_name(
            f'{input_path.stem}_{canvas_width}x{canvas_height}_D{text_rows}_{background}.png'
        )
    canvas.save(output_path)

    print(f'Transformation completed. Saved as {output_path.name}.')
    print(f'Output image size: {canvas_width}x{canvas_height}')
    print(f'Text density: {text_cols}x{text_rows}')
    print(f'Elapsed time: {time.time() - since:.4} second(s)')


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79



代码比较多,这里不做展示,需要的可以去下载。
python代码实现把图片生成字符画(黑白色、彩色图片)




总结

关于python代码学习手把手教你将图片变成字符画(骚操作)就介绍到这了,上述实例对大家学习使用Python有一定的参考价值,希望大家阅读完这篇文章能有所收获。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/854248
推荐阅读
相关标签
  

闽ICP备14008679号