How can you write code in Python to convert videos into high-definition motion pictures without relying on expensive third-party tools or enduring low-quality output?
For specific implementation, please refer to this blog post. This technology is very useful for creating presentations, social media content or blog posts, because it allows you to easily convert video clips into clear GIF animations.
Background
Recently, I needed to prepare some dynamic pictures for a PPT defense, and these pictures needed to be extracted from a video. I tried some online tools and paid software, but found that the conversion results were either unclear, watermarked, or required payment. So, I decided to write the code myself to achieve this task.
Technology stack
Before we begin, let’s first understand the technology stack we will be using:
– Python: As a programming language of choice, Python is a powerful and easy-to-use language suitable for processing images and videos.
– OpenCV: This is a library widely used for computer vision tasks and we will use it to process video frames.
– imageio: This library will help us to read video files and save frames as GIF.
Steps
Here are the main steps to convert videos into HD motion pictures:
1. Install the required libraries:
Install the required Python libraries using pip or conda:
pip install opencv-python imageio
I divided the whole process into three parts for implementation:
Step 1: Convert video to image using opencv
Read the video through VideoCapture, and then imwrite to save the picture. code show as below:
def video_to_image(videoPath,imgPath,save_format = '.jpg',imgNumber = 0,nameLength = 4): ''' params: videoPath: video path such as u'E:\Test/123.mp4' imgPath: image path, for example r'F:\Test/tu/' #Save the image path, add / slash at the end of the path save_format: The saved image format, the default is jpg and can be changed to '.png' imgNumber: The number of names saved in the image defaults to 0. ''' print("How to convert video to picture") if imgPath[-1] != '/':imgPath + '/' capture = cv2.VideoCapture(videoPath) frame_num = int(capture.get(cv2.CAP_PROP_FRAME_COUNT)) suc = capture.isOpened() # Whether it was successfully opened frame_count = imgNumber # The number of pictures to start from while suc: try: frame_count + = 1 suc, frame = capture.read() cv2.imwrite(imgPath + str(frame_count).zfill(4) + save_format, frame) # The zfill() method returns a string of specified length. The original string is right-aligned and filled with 0s in front. #:str.zfill(width) parameter width if frame_num == frame_count: suc=False except: break capture.release() print("Video to picture conversion ends! ")
In the second step, the picture set exported from the video is converted into a gif picture
The imageio.get_writer used writes pictures as a gif file stream.
imageio.get_writer(uri = gifname,mode = "I",fps = 25)
These three parameters respectively represent:
uri: The name of the synthesized gif animation, which can be changed at will. mode: operating mode, I means multiple images, no need to change. fps: Frame rate, which is the number of frames transmitted per second. The larger the value, the faster the GIF playback speed.
code show as below:
def image_to_gif(st_imagename=1,end_imagename=1,gifname = "demo.gif"): import imageio ''' uri: The name of the synthesized gif animation, which can be changed at will. mode: operating mode, I means multiple images, no need to change. fps: Frame rate, which is the number of frames transmitted per second. The larger the value, the faster the GIF playback speed. gifname: saved gif name ''' os.chdir(os.getcwd()) if not os.path.exists("images"): os.makedirs("images") with imageio.get_writer(uri = gifname,mode = "I",fps = 25) as writer: for i in range(st_imagename, end_imagename + 1): #How many images to choose? print(f"Processing the {i}th picture") filename = str(i).zfill(4) file_path = os.path.join(os.getcwd(),'images',filename) writer.append_data(imageio.imread(file_path + ".jpg"))
The last step is to integrate the above two steps to convert the video into a gif image
The following is the code for the third step
def video_to_gif(videoPath,resultName,fps=25): ''' :param videoPath: Video path absolute path. And the path should not contain Chinese characters :param resultName: output gif file name :param fps: saved gif frame rate, fps defaults to 25 ''' sample = [chr(i) for i in range(97,97 + 26)] + [str(i) for i in range(10)] random_name = "_" + "".join(random.sample(sample,10)) #Used to temporarily store data images #shutil.rmtree(file_path) #Delete if not os.path.exists(random_name): os.makedirs(random_name) tmp_path = os.path.join(os.getcwd(),random_name) + '/' print("step 1 loading:video_to_image start") video_to_image(videoPath,tmp_path) #Video conversion completed print("step 1 finished:video_to_image end") image_nums = len(os.listdir(tmp_path)) image_nums = 375 if image_nums > 375 else image_nums #TODO The default upper limit is 15s, that is: 25 * 15 = 375 photos print("step 2 loading:image_to_gif start") image_to_gif(st_imagename=1,end_imagename=image_nums,gifname = resultName) print("step 2 finished:image_to_gif end") shutil.rmtree(random_name) print("All Finished")
The code of the entire project has been uploaded to: askxiaozhang/Python_tools: To provide some like practical tools that png turn to gif or mp4 turn to gif by Python. (github.com)
Brothers and sisters in need can go to Fork and star. Everyone is welcome to join this project and contribute to open source! ~
Below is the entire project code:
import string import imageio import os import cv2 import shutil import base64 import random def video_to_image(videoPath,imgPath,save_format = '.jpg',imgNumber = 0,nameLength = 4): ''' params: videoPath: video path such as u'E:\Test/123.mp4' imgPath: image path, for example r'F:\Test/tu/' #Save the image path, add / slash at the end of the path save_format: The saved image format, the default is jpg and can be changed to '.png' imgNumber: The number of names saved in the image defaults to 0. ''' print("How to convert video to picture") if imgPath[-1] != '/':imgPath + '/' capture = cv2.VideoCapture(videoPath) frame_num = int(capture.get(cv2.CAP_PROP_FRAME_COUNT)) suc = capture.isOpened() # Whether it was successfully opened frame_count = imgNumber # The number of pictures to start from while suc: try: frame_count + = 1 suc, frame = capture.read() cv2.imwrite(imgPath + str(frame_count).zfill(4) + save_format, frame) # The zfill() method returns a string of specified length. The original string is right-aligned and filled with 0s in front. #:str.zfill(width) parameter width if frame_num == frame_count: suc=False except: break capture.release() print("Video to picture conversion ends! ") def image_to_gif(file_path,st_imagename=1,end_imagename=1,gifname = "demo.gif"): import imageio ''' uri: The name of the synthesized gif animation, which can be changed at will. mode: operating mode, I means multiple images, no need to change. fps: Frame rate, which is the number of frames transmitted per second. The larger the value, the faster the GIF playback speed. gifname: saved gif name ''' # os.chdir(os.getcwd()) # if not os.path.exists("images"): # os.makedirs("images") with imageio.get_writer(uri = gifname,mode = "I",fps = 25) as writer: for i in range(st_imagename, end_imagename + 1): #How many images to choose? print(f"Processing the {i}th picture") filename = str(i).zfill(4) #file_path = os.path.join(os.getcwd(),'images',filename) file_path2 = file_path + filename + ".jpg" writer.append_data(imageio.imread(file_path2)) def video_to_gif(videoPath,resultName,fps=25): ''' :param videoPath: Video path absolute path. And the path should not contain Chinese characters :param resultName: output gif file name :param fps: saved gif frame rate, fps defaults to 25 ''' sample = [chr(i) for i in range(97,97 + 26)] + [str(i) for i in range(10)] random_name = "_" + "".join(random.sample(sample,10)) #Used to temporarily store data images #shutil.rmtree(file_path) #Delete if not os.path.exists(random_name): os.makedirs(random_name) tmp_path = os.path.join(os.getcwd(),random_name) + '/' print("step 1 loading:video_to_image start") video_to_image(videoPath,tmp_path) #Video conversion completed print("step 1 finished:video_to_image end") image_nums = len(os.listdir(tmp_path)) image_nums = 375 if image_nums > 375 else image_nums #TODO The default upper limit is 15s, that is: 25 * 15 = 375 photos print("step 2 loading:image_to_gif start") image_to_gif(tmp_path,st_imagename=1,end_imagename=image_nums,gifname = resultName) print("step 2 finished:image_to_gif end") shutil.rmtree(random_name) print("All Finished") if __name__ == '__main__': video_to_gif(r"E:\Python_tools\Python_tools\video\test.mp4","test1.gif")
The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Python entry skill treeHomepageOverview 363451 people are learning the system