Created
July 3, 2022 19:23
-
-
Save FabulousCodingFox/a1d59a7c5dd3bd6dcd6a982a44dc13c0 to your computer and use it in GitHub Desktop.
A small script written in python to convert videos/photos to their ascii counterparts.
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
from PIL import Image | |
from PIL import ImageFont | |
from PIL import ImageDraw | |
import cv2,time,os | |
from moviepy.editor import * | |
from tkinter import filedialog as fd | |
def im_to_ascii(im:Image,width:int=640,keepAlpha:bool=True,highContrastMode:bool=False,fontResolution:int=5): | |
ratio:float = width/im.size[0] | |
im:Image = im.resize((int(im.size[0]*ratio),int(im.size[1]*ratio)),Image.NEAREST).convert("LA") | |
if highContrastMode: ramp:str = "@. .:-=+*#%@" | |
else : ramp:str = " .:-=+*#%@" | |
c:list[str] = [] | |
for h in range(im.size[1]): | |
row:list[str] = [] | |
for w in range(im.size[0]): | |
col:tuple = im.getpixel((w,h)) | |
if keepAlpha and col[1]<=127: row.append(" ") | |
else: row.append(ramp[int((col[0]/255)*len(ramp))-1]) | |
c.append(" ".join(row)) | |
w:int = im.size[0] * fontResolution * 5 | |
h:int = im.size[1] * fontResolution * 6 | |
font:ImageFont = ImageFont.truetype("monogram.ttf", 7 * fontResolution) | |
img = Image.new("RGB",(w,h),(0,0,0)) | |
ImageDraw.Draw(img).text( | |
(0, 0), | |
"\n".join(c), | |
(255,255,255), | |
font=font | |
) | |
return img | |
def videoFileToAscii(path:str,skip:bool=False): | |
if not skip: | |
def extractFrames(path:str)->tuple[int,int,int]: | |
print("Extracting Frames...") | |
starttime = time.time() | |
vidcap = cv2.VideoCapture(path) | |
success,image = vidcap.read() | |
count = 0 | |
length = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT)) | |
while success: | |
cv2.imwrite("frame/frame%d.png" % count, image) | |
success,image = vidcap.read() | |
count += 1 | |
if time.time()-starttime>=2: print(int((count/length)*100),"%",sep="",end="\r");starttime=time.time() | |
return count,length,vidcap.get(cv2.CAP_PROP_FPS) | |
videoFrames, videoLength, videoFramerate = extractFrames(path) | |
videoTargetWidth = 120 | |
videoTargetFramerate = 10 | |
print("Converting Frames...") | |
for frame in range(0,videoFrames,int(videoFramerate/videoTargetFramerate)): | |
starttime = time.time() | |
with Image.open("frame/frame%d.png" % frame) as im: | |
im_to_ascii(im,videoTargetWidth,fontResolution=4).save("frame/frame%d.png" % frame) | |
if time.time()-starttime>=2: print(int((frame/videoFrames)*100),"%",sep="",end="\r");starttime=time.time() | |
else: | |
videoFrames = 359 | |
videoFramerate = 30 | |
videoTargetFramerate = 10 | |
clip = ImageSequenceClip([f"frame/frame{frame}.png" for frame in range(0,videoFrames,int(videoFramerate/videoTargetFramerate))], fps = videoTargetFramerate) | |
clip.write_videofile(os.path.join(os.path.dirname(__file__),"output.mp4")) | |
if __name__ == "__main__": | |
path = fd.askopenfile(initialdir=os.path.dirname(__file__)) | |
if True in [path.name.endswith(ext) for ext in [".mp4",".mkv",".avi",".mov"]]: | |
videoFileToAscii(path.name) | |
elif True in [path.name.endswith(ext) for ext in [".jpg",".jpeg",".png",".gif"]]: | |
with Image.open(path.name) as im: | |
i = im_to_ascii(im,width=516) | |
i.save("output.png") | |
i.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment