Last active
May 27, 2024 09:38
-
-
Save mankind/d96d31497a43d3fabe8c636235ab6eda to your computer and use it in GitHub Desktop.
Scrolling Text Animation with Python - https://pjoshi15.com/scrolling-text-python/ - https://pjoshi15.com/create-typewriter-effect-animation-using-python/ - https://prateekjoshi.medium.com/creating-magic-with-python-visual-effects-and-animation-for-content-wizards-422f274d7c0f - https://github.com/ramsrigouthamg/Supertranslate.ai/blob/main/Scrol…
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
""" | |
https://pjoshi15.com/scrolling-text-python/ | |
How to Create Scrolling Text Animation with Python | |
Scrolling text in a video or gif can add lots of value to the content and present key information in a small amount of space. To create our scrolling text animation video, we’ll use OpenCV (cv2) paired with the Python Imaging Library (PIL) in this article. Our code will also allow the users to adjust the speed of the scrolling text and also the direction of movement of the text. Ready to get started creating scrolling text animation with Python? Let’s start with right-to-left text. | |
Python function for creating scrolling text video | |
Below is a Python function that takes in inputs like a text string, speed of animation, direction of scrolling animation and a few other parameters to create a video of scrolling text either left-to-right or right-to-left. | |
Inside the function, we have set the width and height of the video to 300 and 200 pixels, respectively. The video background color has been set to black (0,0,0) and the color of the text is going to be white (255, 255, 255). The font that we are using for the text is Arial font, so make sure you have the arial.tff file in the working directory. Feel free to change these parameters as per your requirement. | |
""" | |
def create_scrolling_text_video(text, font_path, font_size, speed, output_file, direction='left'): | |
image_width=300 | |
image_height=200 | |
text_color=(255, 255, 255) # scrolling text color | |
bg_color=(0, 0, 0) # background color | |
font = ImageFont.truetype(font_path, font_size) | |
# get size of the input text string | |
text_width, text_height = font.getsize(text) | |
# number of frames | |
num_frames = text_width + image_width | |
fourcc = cv2.VideoWriter_fourcc(*"mp4v") | |
video_writer = cv2.VideoWriter(output_file, fourcc, speed, (image_width, image_height)) | |
# create frames for text scrolling | |
for i in range(num_frames): | |
img = Image.new("RGB", (image_width, image_height), bg_color) | |
draw = ImageDraw.Draw(img) | |
if direction == 'left': | |
x = image_width - i | |
elif direction == 'right': | |
x = -(image_width - i) | |
else: | |
raise ValueError("Invalid direction. Choose either 'left' or 'right'.") | |
y = (image_height - text_height) // 2 | |
draw.text((x, y), text, font=font, fill=text_color) | |
# Convert the image to an OpenCV frame | |
frame = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) | |
video_writer.write(frame) | |
video_writer.release() | |
""" | |
The number of frames has been set equal to the sum of the frame width and the input text string width. This will allow the entire text string to pass the frame from first character till the last character. | |
Then on each frame, at the center, the text is overlayed. After that all the frames are combined to create an mp4 video and then it is saved at the specified location in your system. | |
Horizontal scrolling text animation: right-to-left | |
Now we will call the above function to create a short video of scrolling text from right-to-left. The input text string is “This is a scrolling text animation example”. | |
""" | |
text = "This is a scrolling text animation example." | |
font_path = "arial.ttf" # Path to your desired font file (e.g., arial.ttf or path to any other TTF font file) | |
font_size = 32 | |
speed = 90 # Higher value makes the text scroll faster | |
output_file = "scrolling_text.mp4" | |
create_scrolling_text_video(text, font_path, font_size, speed, output_file, direction = "left") | |
""" | |
Horizontal scrolling text animation: left-to-right | |
Let’s change the direction of the scrolling text and make it left-to-right. All we have to do is pass ‘left’ as the value for the ‘direction’ argument. | |
""" | |
text = "This is a scrolling text animation example." | |
font_path = "arial.ttf" # Path to your desired font file (e.g., arial.ttf or path to any other TTF font file) | |
font_size = 26 | |
speed = 90 # Higher value makes the text scroll faster | |
output_file = "scrolling_text_right.mp4" | |
create_scrolling_text_video(text, font_path, font_size, speed, output_file, direction = "right") | |
""" | |
Horizontal scrolling text animation: both directions | |
Now let’s modify the scrolling text animation function and implement dual text scrolling animation from both the directions. | |
""" | |
# this code uses llama | |
# | |
""" | |
The num_frames variable is not pre-selected in the provided code. It is an input parameter that represents the desired number of frames for the scrolling text animation. The code assumes that the caller will provide an appropriate value for num_frames based on the desired duration and frame rate of the animation. | |
Regarding the for loop, the provided code does handle the loop using the moviepy package. The TextClip object created in the code represents the scrolling text animation, and its duration is set using the set_duration() method. The CompositeVideoClip object combines the text clip with the background clip, and the write_videofile() method is used to write the final video file. | |
Why num_frames is a pre-selected number: | |
In the provided code, num_frames is indeed a pre-selected number. This is because the MoviePy library doesn't require you to explicitly create each frame like OpenCV does. Instead, you can specify the duration of the clip and let MoviePy handle the frame generation. The set_duration method is used to set the duration of the TextClip, and MoviePy will automatically generate the required number of frames based on the specified duration and FPS. | |
Handling the for i in range(num_frames): loop: | |
You're right; the provided code doesn't directly translate the for i in range(num_frames): loop from OpenCV to MoviePy. This is because MoviePy's TextClip and CompositeVideoClip classes handle the animation and frame generation internally. | |
To achieve a similar effect, you can use MoviePy's animate method to animate the text clip's position over time. Here's an updated code snippet that demonstrates how to scroll the text across the video: | |
In this updated code, we use the animate method to animate the text clip's position over time. The animate_text function returns the x-coordinate of the text clip based on the current time t. This will create a scrolling effect where the text moves across the video. | |
""" | |
## | |
# adapting the code to use moviepy | |
from moviepy.editor import TextClip, ColorClip, CompositeVideoClip | |
# Define the text, font, and other parameters | |
text = "Your text here" | |
font = "Your font here" | |
text_height = 50 | |
bg_color = (255, 255, 255) # White background | |
text_color = (0, 0, 0) # Black text | |
fps = 30 | |
duration = 5 # seconds | |
image_width = 640 # Width of the video frame | |
image_height = 480 # Height of the video frame | |
# Create a blank video clip with the desired background color | |
bg_clip = ColorClip(size=(image_width, image_height), color=bg_color, duration=duration) | |
# Create a text clip | |
text_clip = TextClip(text, font=font, color=text_color, size=text_height, align='center') | |
# Animate the text clip's position over time | |
def animate_text(t): | |
if direction == 'left': | |
x = image_width - t * fps | |
elif direction == 'right': | |
x = -image_width + t * fps | |
else: | |
raise ValueError("Invalid direction. Choose either 'left' or 'right'.") | |
""" | |
image_height is used to calculate the y-coordinate of the text, (image_height - text_height) // 2, which centers the text vertically. | |
You should define image_height based on your specific video resolution or image size | |
""" | |
y = (image_height - text_height) // 2 # Keep the y-coordinate constant | |
return x, y | |
# https://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html#moviepy.video.VideoClip.VideoClip.set_position | |
# # clip's position is horizontally centered, and moving up ! | |
# clip.set_position(lambda t: ('center', 50+t) ) | |
text_clip = text_clip.set_position(lambda t: animate_text(t) ) | |
# text_clip = text_clip.set_position(animate_text) | |
# Combine the text clip and the background clip | |
video_clip = CompositeVideoClip([bg_clip, text_clip]) | |
# Write the video clip to a file | |
video_clip.write_videofile("scrolling_text.mp4", fps=fps) | |
## another approach using @Mixtral-8x7B-Chat | |
""" | |
This code creates a TextClip instance, which scrolls from right to left if the direction argument is set to 'left' and from left to right if the direction argument is set to 'right'. | |
The key difference between the original code and the refactored code is that the refactored code uses TextClip to manage the scrolling text and the time, while the original code uses a loop to create each frame. | |
In the refactored code, the text_scrolling_clip function takes care of the scrolling by setting the start time of the TextClip and calculating the position of the text. | |
The mplfig_to_npimage function is used to convert the TextClip instance into a numpy array (image) which is then added to the background color (bg_color) using the + operator. | |
Finally, the write_videofile method is used to generate the output video. | |
Note: The mplfig_to_npimage function is used to work around some TextClip positioning issues. In some cases, using set_position and resize directly might not work as expected, so this function is used to ensure proper positioning. | |
from moviepy.video.io.bindings import mplfig_to_npimage | |
https://zulko.github.io/moviepy/getting_started/working_with_matplotlib.html#simple-matplotlib-example | |
""" | |
from moviepy.editor import TextClip | |
from moviepy.video.io.bindings import mplfig_to_npimage | |
def text_scrolling_clip(text, image_width, image_height, bg_color, text_color, font, direction, num_frames): | |
text_clip = TextClip(text, font=font, color=text_color) | |
text_clip = text_clip.set_position(lambda t: (image_width - t * 2, (image_height - text_clip.size[1]) // 2)) | |
if direction == 'left': | |
text_clip = text_clip.set_start(-num_frames) | |
composite_clip = ( | |
mplfig_to_npimage( | |
plt.gcf() | |
).set_duration(num_frames / fps) | |
+ text_clip | |
) | |
return composite_clip | |
# Usage example | |
num_frames = 100 | |
fps = 24 | |
text = "This is a moving text" | |
image_width = 1280 | |
image_height = 720 | |
bg_color = (255, 255, 255) | |
text_color = (0, 0, 0) | |
font = "Arial" | |
direction = 'left' | |
clip = text_scrolling_clip(text, image_width, image_height, bg_color, text_color, font, direction, num_frames) | |
clip.write_videofile("text_scrolling.mp4", fps=fps) |
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
""" | |
https://pjoshi15.com/create-typewriter-effect-animation-using-python/ | |
Create Typewriter Effect Animation Using Python | |
Typing animation is an eye-catching video effect in today’s times of reels and short videos. In this tutorial, I will teach you how to create a typewriter animation using Python. | |
Once you know how to implement this animation, you can then use it to create interactive and dynamic presentations, illustrations, and social media content. | |
Understanding the Typewriter Effect | |
The typewriter effect animation is a popular aesthetic choice that simulates the appearance of text being typed onto the screen one character at a time. Often used in videos, presentations, and web-based projects, this effect helps deliver messages uniquely and engagingly. | |
When we talk about typing animation using Python, we’re referring to creating a script that simulates the typing process. Python libraries such as OpenCV, Pillow, and numpy facilitate implementing the typing effect. By leveraging these libraries, we can produce interactive text-based applications as well as visuals for a variety of content. | |
Applying the typing animation in video requires a somewhat different approach compared to static text-based applications. | |
For video, we may have to employ frame-by-frame processing to create the typing effect, allowing us to time the appearance of each character precisely. | |
Setting Up Python for Animation | |
First, ensure that you have Python 3.x installed on your system. If you’re unsure which version you have run python --version or python3 --version in your command prompt or terminal. | |
If you need a newer version, download it from the official Python website. | |
With Python ready, let’s install the necessary third-party packages. Run the following commands in your terminal or command prompt: | |
""" | |
# pip install -U opencv-python | |
# pip install pillow | |
""" | |
Creating Text Typing Animation using Python | |
Creating typing animation using Python is relatively straightforward, and we’ll guide you through it step by step. | |
By using this approach, you can give your videos, presentations, or other applications a professional touch with an eye-catching typing effect. | |
Let’s load the libraries | |
""" | |
# import cv2 | |
# import numpy as np | |
# from PIL import ImageFont, ImageDraw, Image | |
""" | |
Define Function to Create Typing Animation | |
This Python function will create the typewriter effect animation and add that animation to a video. The text font size, video duration, and frames per second in the video can be controlled by the user. | |
We can also add colors and sound to this video, but let’s keep it aside for some other tutorial. | |
""" | |
def create_video_with_typewriter_effect(text, output_filename, fontsize=30, video_fps=30, video_duration=10): | |
font = ImageFont.truetype("arial.ttf", fontsize) | |
# dimensions of video | |
video_width = 800 | |
video_height = 60 | |
video_size = (video_width, video_height) | |
video = cv2.VideoWriter(output_filename, | |
cv2.VideoWriter_fourcc(*'mp4v'), | |
video_fps, | |
video_size) | |
# Calculate the text width and height | |
text_width, text_height = font.getsize(text) | |
# Video settings | |
text_fade_duration = 1 # seconds | |
text_typing_duration = video_duration - text_fade_duration | |
# Calculate the number of frames for the typewriter effect | |
num_typing_frames = int(text_typing_duration * video_fps) | |
num_fade_frames = int(text_fade_duration * video_fps) | |
# Typing effect | |
for frame_idx in range(num_typing_frames): | |
frame = np.zeros((video_height, video_width, 3), dtype=np.uint8) | |
frame_pil = Image.fromarray(frame) | |
draw = ImageDraw.Draw(frame_pil) | |
current_text = text[:int(len(text) * frame_idx / num_typing_frames)] | |
draw.text((10, 10), current_text, font=font, fill=(255, 255, 255, 255)) | |
video.write(np.array(frame_pil)) | |
# Fade out effect | |
for frame_idx in range(num_fade_frames): | |
frame = np.zeros((video_height, video_width, 3), dtype=np.uint8) | |
frame_pil = Image.fromarray(frame) | |
draw = ImageDraw.Draw(frame_pil) | |
alpha = 255 - int(255 * frame_idx / num_fade_frames) | |
draw.text((10, 10), text, font=font, fill=(255, 255, 255, alpha)) | |
video.write(np.array(frame_pil)) | |
video.release() | |
""" | |
Pass an input sentence to the function above along with a file name for the output video. The typing effect will be applied to this input sentence. | |
If you want to change the speed of the typing animation effect then you can also pass different values of video_fps and video_duration arguments to the function | |
""" | |
text = "This is a typewriter animation created using Python." | |
output_filename = "typewriter_animation.mp4" | |
create_video_with_typewriter_effect(text, output_filename) | |
""" | |
Finally, we get the following output video of typewriter-effect animation built using Python. | |
End Notes | |
In this article, we’ve explored an exciting technique of creating typewriter-effect animations using Python. | |
""" | |
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
# Generate YouTube Shorts Videos using Python | |
# https://pjoshi15.com/generate-youtube-shorts-python/ | |
# import cv2 | |
# import os | |
def create_video_from_images(images_folder, output_video, fps=10, duration=6): | |
images = sorted(os.listdir(images_folder)) | |
# create path to the input images | |
img_path = os.path.join(images_folder, images[0]) | |
# load image | |
frame = cv2.imread(img_path) | |
# extract dimensions of the image | |
height, width, channels = frame.shape | |
video_writer = cv2.VideoWriter(output_video, | |
cv2.VideoWriter_fourcc(*'mp4v'), | |
fps, | |
(width, height)) | |
# total number of frames for the video | |
frames_per_image = fps * duration | |
for image in images: | |
img_path = os.path.join(images_folder, image) | |
frame = cv2.imread(img_path) | |
for _ in range(frames_per_image): | |
video_writer.write(frame) | |
video_writer.release() | |
print(f"Video {output_video} created successfully") | |
# generate video | |
create_video_from_images("/images", "out.mp4") | |
### moviepy implementation | |
from moviepy.editor import ImageClip, concatenate_videoclips | |
import os | |
def create_video_from_images(images_folder, output_video, fps=10, duration=6): | |
# Get a list of image files in the folder | |
image_files = [img for img in os.listdir(images_folder) if img.endswith(".png")] | |
# Create video clips from the images | |
clips = [ImageClip(os.path.join(images_folder, img)).set_duration(duration) for img in image_files] | |
# Concatenate the clips into a single video | |
final_clip = concatenate_videoclips(clips, method="compose") | |
# Write the video to the specified output file | |
final_clip.write_videofile(output_video, fps=fps, codec="libx264") | |
print(f"Video {output_video} created successfully") | |
# Example usage | |
images_folder = "path/to/your/images" | |
output_video = "output_video.mp4" | |
create_video_from_images(images_folder, output_video) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment