基本信息
源码名称:python实现图片和视频转ASCII码
源码大小:3.98KB
文件格式:.py
开发语言:Python
更新时间:2020-03-12
   源码介绍
图片和视频转ASCII码,输出图片或视频

"""
python Video&Image2Text.py file_name [-color]
"""

import os
import cv2
import sys
import numpy as np
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import time

chars = '#@&%x*^,. '
color = False


def handle_one_frame(img):
    start = time.time()
    img = img.convert('L') if not color else img  # convert to gray if color is False.
    img = np.array(img)
    width = img.shape[1]
    height = img.shape[0]
    output_img = Image.new(mode = 'RGB' if color else 'L', size = (width, height),
                           color = (255, 255, 255) if color else (255,))  # use '1' rather than 'L' is more clear.
    draw = ImageDraw.Draw(output_img)  # to write text to image.
    font = ImageFont.truetype(font = 'segoeui.ttf', size = 13 if color else 9)
    # write a char in every (block_size X block_size) area, and block_size should be odd.
    block_size = 11 if color else 9
    half_block_size = int(block_size / 2)
    for i in range(half_block_size, width, block_size):
        for j in range(half_block_size, height, block_size):
            # calculate each block's total gray value.
            try:
                if not color:
                    array = [[img[x][y] for y in range(i - half_block_size, i   half_block_size   1)] for x in
                             range(j - half_block_size, j   half_block_size   1)]  # 2d array.
                    total = sum([sum(array[k]) for k in range(len(array))])
                    average_value = int(total / (block_size * block_size))  # average gray value.
                    draw.text((i, j), chars[int(average_value / 25)], font = font)
                else:
                    arrays = [
                        [[img[x][y][channel] for y in range(i - half_block_size, i   half_block_size   1)] for x in
                         range(j - half_block_size, j   half_block_size   1)] for channel in range(3)]
                    totals = [sum([sum(arrays[i][k]) for k in range(len(arrays[i]))]) for i in range(len(arrays))]
                    average_values = [int(totals[i] / (block_size * block_size)) for i in range(len(totals))]
                    draw.text((i, j), chars[int(sum(average_values) / (25 * 3))], font = font,
                              fill = (average_values[0], average_values[1], average_values[2]))
            except:
                continue
    end = time.time()
    print('cost: ', end - start, 's')
    return output_img


def main(file):
    if str(os.path.splitext(file)[1]).lower() in ['.jpg', '.png']:
        img = Image.open(file)
        output_img = handle_one_frame(img)
        output_img.save(os.path.splitext(file)[0]   '--output.jpg')
    elif str(os.path.splitext(file)[1]).lower() in ['.mp4']:
        video = cv2.VideoCapture(file)
        state, img = video.read()
        # create VideoWriter to write video.
        fps = int(video.get(cv2.CAP_PROP_FPS))
        width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
        output_video = cv2.VideoWriter(os.path.splitext(file)[0]   '--output.avi',
                                       cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), fps, (width, height))
        count = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
        while state:
            try:
                count -= 1
                state, img = video.read()
                img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))  # cv2 image to PIL image.
                output_img = handle_one_frame(img)
                output_img = output_img.convert('RGB')
                img = cv2.cvtColor(np.array(output_img), cv2.COLOR_RGB2BGR)  # PIL image to cv2.
                output_video.write(img)
                print(count)
            except Exception as e:
                print(e)
        output_video.release()
        video.release()


if __name__ == '__main__':
    if len(sys.argv) == 3 and sys.argv[2] == '-color':
        color = True
    main(sys.argv[1])