Skip to content

Instantly share code, notes, and snippets.

@FabulousCodingFox
Created July 3, 2022 19:23
Show Gist options
  • Save FabulousCodingFox/a1d59a7c5dd3bd6dcd6a982a44dc13c0 to your computer and use it in GitHub Desktop.
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.
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