Last active
October 10, 2020 16:40
-
-
Save Alvant/dc0c5799f41982a9a528fce6f761b4c2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import argparse | |
import os | |
import warnings | |
from PIL import ( | |
Image, | |
ImageDraw, | |
ImageFont, | |
) | |
import cv2 | |
# https://github.com/RameshAditya/asciify | |
from asciify import runner | |
FONT_FILE_PATH = 'Roboto.ttf' # need mono font for proper width/height sizes | |
def save_frames(input_file_path, output_folder_path): | |
# https://stackoverflow.com/a/17109400/8094251 | |
vc = cv2.VideoCapture(input_file_path) | |
current_index = 1 | |
if vc.isOpened(): | |
rval , frame = vc.read() | |
else: | |
rval = False | |
if not os.path.isdir(output_folder_path): | |
os.mkdir(output_folder_path) | |
while rval: | |
rval, frame = vc.read() | |
cv2.imwrite( | |
filename=os.path.join(output_folder_path, str(current_index) + '.jpg'), | |
img=frame | |
) | |
current_index = current_index + 1 | |
cv2.waitKey(1) | |
vc.release() | |
def save_ascii_images(input_folder_path, output_folder_path): | |
image_names = os.listdir(input_folder_path) | |
image_names = [ | |
file_name for file_name in image_names | |
if os.path.isfile(os.path.join(input_folder_path, file_name)) | |
] | |
numbers = [int(f.split('.')[0]) for f in image_names] | |
source_image_extension = os.path.splitext(image_names[0])[-1] | |
target_image_extension = '.png' | |
if not os.path.isdir(output_folder_path): | |
os.mkdir(output_folder_path) | |
for number in sorted(numbers): | |
image_file_path = os.path.join(input_folder_path, f'{number}{source_image_extension}') | |
ascii_text = runner(image_file_path) | |
if ascii_text is None: | |
warnings.warn(f'Text is None for image "{image_file_path}"!') | |
else: | |
_save_image( | |
text=ascii_text, | |
path=os.path.join(output_folder_path, f'{number}{target_image_extension}'), | |
) | |
def _save_image(text, path, font_size=22): | |
# https://code-maven.com/create-images-with-python-pil-pillow | |
# https://stackoverflow.com/questions/17856242/how-to-convert-a-string-to-an-image | |
img = Image.new( | |
mode='RGB', | |
size=(1300, 955 - 2 * 17 * 2 - 4), # TODO: need to adjust this | |
color=(255, 255, 255), | |
) | |
draw = ImageDraw.Draw(img) | |
if os.path.isfile(FONT_FILE_PATH): | |
font = ImageFont.truetype(FONT_FILE_PATH, font_size) | |
else: | |
warnings.warn(f'No font file "{FONT_FILE_PATH}" found!') | |
font = None | |
draw.text( | |
xy=(0, -8 - 17 * 2), # TODO: need to adjust this | |
text=text, | |
font=font, | |
fill=(0, 0, 0), | |
spacing=-7, # so as to remove spacing between lines completely | |
) | |
# May be helpful for determining text size | |
# print(draw.textsize(text)) | |
img.save(path) | |
def save_mp4(input_folder_path, output_file_path, extension='.png'): | |
# https://tsaith.github.io/combine-images-into-a-video-with-python-3-and-opencv-3.html | |
images = [] | |
for f in os.listdir(input_folder_path): | |
if f.endswith(extension): | |
images.append(f) | |
images = sorted(images, key=lambda image: int(image.split('.')[0])) | |
# Determine the width and height from the first image | |
image_path = os.path.join(input_folder_path, images[0]) | |
frame = cv2.imread(image_path) | |
cv2.imshow('video', frame) | |
height, width, channels = frame.shape | |
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # be sure to use lower case! | |
output_file = cv2.VideoWriter(output_file_path, fourcc, 20.0, (width, height)) | |
for image in images: | |
image_path = os.path.join(input_folder_path, image) | |
frame = cv2.imread(image_path) | |
output_file.write(frame) | |
cv2.imshow('video', frame) | |
if (cv2.waitKey(1) & 0xFF) == ord('q'): # Hit `q` to exit | |
break | |
output_file.release() | |
cv2.destroyAllWindows() | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument( | |
"--input", | |
required=True, | |
help="Input .mp4.", | |
) | |
parser.add_argument( | |
"--frames-folder", | |
required=True, | |
help="Folder for the original frames of the video file as images.", | |
) | |
parser.add_argument( | |
"--ascii-folder", | |
required=True, | |
help="Folder for ASCII images: one ASCII image for each frame of the original video.", | |
) | |
parser.add_argument( | |
"--output", | |
required=True, | |
help="Output .mp4.", | |
) | |
args = vars(parser.parse_args()) | |
input_file_path = args['input'] | |
frames_folder_path = args['frames_folder'] | |
ascii_folder_path = args['ascii_folder'] | |
output_file_path = args['output'] | |
save_frames( | |
input_file_path=input_file_path, | |
output_folder_path=frames_folder_path, | |
) | |
save_ascii_images( | |
input_folder_path=frames_folder_path, | |
output_folder_path=ascii_folder_path, | |
) | |
save_mp4( | |
input_folder_path=ascii_folder_path, | |
output_file_path=output_file_path, | |
) | |
# TODO: maybe one will still need to use an external tool | |
# to reconvert .mp4 to .mp4 to fix some stuff | |
# One more step could be: .mp4 to .gif (using Giphy, for example) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment