"""
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])