# -------------- CREATE PAN / ZOOM / FLY-IN / FLY-OUT ANIMATIONS---------------- ''' This Python and OpenCV code is intended to create functions to generate the animations available in Microsoft PowerPoint. The first category of aniations are [Wipe, Split, Fly In, Float In, Rise Up, Fly Out, Float Down, Peek In, Peek Out]. All of these look similar and they differ in speed and direction of entrance. The other set is [ Shape, Wheel, Cicle, Box, Diamond ] where the image needs to be in non-orthogonal directions. The third set of animation is [Stretch, Compress, Zoom, Glow and Turn, Pin Wheel] - all of these operations are performed on entire image. The animations in PowerPoint are categories by Entrance, Emphasis and Exit. VideoWriter assumes color by default. VideoWriter has a 5th boolean parameter which one can set False to specify that the video is to be black and white. The the dimensions (width and height) that cv2 expects are the opposite of numpy. ''' #-------------------- USER INPUT STARTS ---------------------------------------- imgFile1 = 'Image-1.png' imgFile2 = 'Image-2.png' vidName1 = 'Vid-1.mp4' vidName2 = 'Vid-2.mp4' fps = 25 clr = (255, 255, 255) # -------------------- USER INPUT ENDS ----------------------------------------- import cv2 import numpy as np img1 = cv2.imread(imgFile1) img2 = cv2.imread(imgFile2) height, width, c = img1.shape def imgVerticalHalf(img, vidName, duration, fps, vid_w, vid_h, clr): #This is equivalent to animation Rise Up / Float Down in MS PowerPoint # .----------------. # | ======= | # | \|/ | # | ' | # | ======= | # | \|/ | # | ' | # !................! # Direction of arrow indicates direction of appearance of image codec = cv2.VideoWriter_fourcc(*'mp4v') vid = cv2.VideoWriter(vidName, codec, fps, (vid_w, vid_h)) height, width, c = img.shape nframes = int(duration * fps) vid.write(img) for i in range(1, nframes, 1): #crop_img = img[y:y+h, x:x+w] crop_ht = min(int(i/nframes * height/2), height//2) half_ht = height // 2 up_crop = img[0:crop_ht, 0:width] dn_crop = img[half_ht:half_ht+crop_ht, 0:width] if (height % 2 == 1): dp = 1 else: dp = 0 padU = vid_h//2 - up_crop.shape[0] padD = vid_h//2 - dn_crop.shape[0] + dp brdr = cv2.BORDER_CONSTANT padImgU = cv2.copyMakeBorder(up_crop, 0,padU, 0,0, brdr, value=clr) padImgD = cv2.copyMakeBorder(dn_crop, 0,padD, 0,0, brdr, value=clr) imgSplit= cv2.vconcat([padImgU, padImgD]) #print(padU, padD, padImgU.shape[0], imgSplit.shape[0]) vid.write(imgSplit) vid.release() def imgVerticalHalfEdge2Centre(img, vidName, duration, fps, vid_w, vid_h, clr): #This is equivalent to animation Rise Up / Float Down in MS PowerPoint # .----------------. # | ======= | # | \|/ | # | ' | # | . | # | /|\ | # | ======= | # !................! # Direction of arrow indicates direction of appearance of image codec = cv2.VideoWriter_fourcc(*'mp4v') vid = cv2.VideoWriter(vidName, codec, fps, (vid_w, vid_h)) height, width, c = img.shape nframes = int(duration * fps) for i in range(1, nframes, 1): #crop_img = img[y:y+h, x:x+w] crop_ht = min(int(i/nframes * height/2), height//2) half_ht = height // 2 up_crop = img[0:crop_ht, 0:width] dn_crop = img[height-crop_ht: height, 0:width] if (height % 2 == 1): dp = 1 else: dp = 0 padU = int(vid_h/2) - up_crop.shape[0] #top,bot, lft,rgt padD = int(vid_h/2) - dn_crop.shape[0] + dp brdr = cv2.BORDER_CONSTANT padImgU = cv2.copyMakeBorder(up_crop, 0,padU, 0,0, brdr, value=clr) padImgD = cv2.copyMakeBorder(dn_crop, padD,0, 0,0, brdr, value=clr) imgSplit= cv2.vconcat([padImgU, padImgD]) vid.write(imgSplit) vid.release() def imgVerticalSplitCentreToEdge(img1, img2, vidName, duration, fps, vid_w, vid_h, clr): #This is equivalent to Rise Up / Float Down with Split in MS PowerPoint # .------------------------. # | IMAGE-1 IMAGE-2 | # | ======= . | # | \|/ /|\ | # | ' ======= | # | . ======= | # | /|\ \|/ | # | ======= ' | # !........................! # Direction of arrow indicates direction of appearance of images codec = cv2.VideoWriter_fourcc(*'mp4v') vid = cv2.VideoWriter(vidName, codec, fps, (vid_w, vid_h)) height, width, c = img1.shape nframes = int(duration * fps) img0 = cv2.hconcat([img1, img2]) vid.write(img0) for i in range(1, nframes, 1): #crop_img = img[y:y+h, x:x+w] crop_ht = min(int(i/nframes * height/2), height//2) half_ht = height // 2 if (height % 2 == 1): dp = 1 else: dp = 0 up_crop = img1[0:crop_ht, 0:width] dn_crop = img1[height-crop_ht: height, 0:width] padU = int(vid_h/2) - up_crop.shape[0] #top,bot, lft,rgt padD = int(vid_h/2) - dn_crop.shape[0] + dp brdr = cv2.BORDER_CONSTANT padImgU = cv2.copyMakeBorder(up_crop, 0,padU, 0,0, brdr, value=clr) padImgD = cv2.copyMakeBorder(dn_crop, padD,0, 0,0, brdr, value=clr) imgSplit1= cv2.vconcat([padImgU, padImgD]) up_crop = img2[half_ht-crop_ht: half_ht, 0:width] dn_crop = img2[half_ht: half_ht+crop_ht, 0:width] padU = int(vid_h/2) - up_crop.shape[0] padD = int(vid_h/2) - dn_crop.shape[0] + dp padImgU = cv2.copyMakeBorder(up_crop, padU,0, 0,0, brdr, value=clr) padImgD = cv2.copyMakeBorder(dn_crop, 0,padD, 0,0, brdr, value=clr) imgSplit2= cv2.vconcat([padImgU, padImgD]) imgSplit = cv2.hconcat([imgSplit1, imgSplit2]) vid.write(imgSplit) vid.release() def imgVerticalSplitEdgeToCentre(img1, img2, vidName, duration, fps, vid_w, vid_h, clr): #This is equivalent to Rise Up / Float Down with Split in MS PowerPoint # .------------------------. # | IMAGE-1 IMAGE-2 | # | , , | # | /|\ /|\ | # | ======= ======= | # | ======= ======= | # | \|/ \|/ | # | ' ' | # !........................! # Direction of arrow indicates direction of appearance of images codec = cv2.VideoWriter_fourcc(*'mp4v') vid = cv2.VideoWriter(vidName, codec, fps, (vid_w, vid_h)) height, width, c = img1.shape nframes = int(duration * fps) img0 = cv2.hconcat([img1, img2]) vid.write(img0) for i in range(1, nframes, 1): #crop_img = img[y:y+h, x:x+w] crop_ht = min(int(i/nframes * height/2), height//2) half_ht = height // 2 if (height % 2 == 1): dp = 1 else: dp = 0 up_crop = img1[half_ht-crop_ht: half_ht, 0:width] dn_crop = img1[half_ht: half_ht+crop_ht, 0:width] padU = int(vid_h/2) - up_crop.shape[0] #top,bot, lft,rgt padD = int(vid_h/2) - dn_crop.shape[0] + dp brdr = cv2.BORDER_CONSTANT padImgU = cv2.copyMakeBorder(up_crop, padU,0, 0,0, brdr, value=clr) padImgD = cv2.copyMakeBorder(dn_crop, 0,padD, 0,0, brdr, value=clr) imgSplit1= cv2.vconcat([padImgU, padImgD]) up_crop = img2[half_ht-crop_ht: half_ht, 0:width] dn_crop = img2[half_ht: half_ht+crop_ht, 0:width] padU = int(vid_h/2) - up_crop.shape[0] padD = int(vid_h/2) - dn_crop.shape[0] + dp padImgU = cv2.copyMakeBorder(up_crop, padU,0, 0,0, brdr, value=clr) padImgD = cv2.copyMakeBorder(dn_crop, 0,padD, 0,0, brdr, value=clr) imgSplit2= cv2.vconcat([padImgU, padImgD]) imgSplit = cv2.hconcat([imgSplit1, imgSplit2]) vid.write(imgSplit) vid.release() # ------------------------------------------------------------------------------ vid_h = height vid_w = width #imgVerticalHalf(img1, vidName1, 5, fps, vid_w, vid_h, clr) #imgVerticalHalfEdge2Centre(img1, vidName2, 5, fps, vid_w, vid_h, clr) imgVerticalSplitCentreToEdge(img1, img2, 'Vid-3.mp4', 5, fps, width*2, vid_h, clr) imgVerticalSplitEdgeToCentre(img1, img2, 'Vid-4.mp4', 5, fps, width*2, vid_h, clr)