getting it to git

This commit is contained in:
Samuel Lazareanu
2023-04-16 16:08:46 +03:00
parent 286f2c9feb
commit c5d1a56dea
24 changed files with 748 additions and 0 deletions

3
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

8
.idea/ChristianPostMaker.iml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.7" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ChristianPostMaker.iml" filepath="$PROJECT_DIR$/.idea/ChristianPostMaker.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

9
Fonts.py Normal file
View File

@@ -0,0 +1,9 @@
class Fonts:
fonts_path: str
fonts_size: int
fonts_chars_limit: int
def __init__(self, fonts_path, fonts_size, fonts_chars_limit):
self.fonts_path = fonts_path
self.fonts_size = fonts_size
self.fonts_chars_limit = fonts_chars_limit

BIN
customers/0-0.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

BIN
customers/1-0.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

BIN
customers/test1/0-0.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

BIN
customers/test1/1-0.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

45
darkenVideos.py Normal file
View File

@@ -0,0 +1,45 @@
import moviepy.video.io.VideoFileClip as vfc
import os
from moviepy import video
def generate_darken_video(video_file, output_path):
video_clip = (vfc.VideoFileClip(video_file, audio=False)
.without_audio())
# Save the final video
darken_clip = video_clip.fl_image(darken)
darken_clip.write_videofile(output_path,
threads=8,
codec="libx264")
# Clean up the temporary files
darken_clip.close()
# A defined function to darken the frames
def darken(frame):
return frame * DARK
def generate_darken_videos(video_folder, output_folder):
# Get a list of video files in the specified folder
video_files = [f"{video_folder}/{file}" for file in os.listdir(video_folder) if file.endswith(".mp4")]
for video_file in video_files:
video_num = video_file.split('/')
video_num = video_num[len(video_num) - 1].split('.')
video_num = video_num[0]
generate_darken_video(video_file, f"{output_folder}/{video_num}.mp4")
video_folder = "E:/Bots/VideoMaker/videos/original/new ones"
output_folder = "E:/Bots/VideoMaker/videos"
DARK = 0.8
generate_darken_videos(video_folder, output_folder)
# Specific video
# video_file = "E:/Bots/VideoMaker/videos/original/7.mp4"
# output_path = "E:/Bots/VideoMaker/videos/darken 40%/7.mp4"
# generate_darken_video(video_file, output_path)

201
ffmpeg.py Normal file
View File

@@ -0,0 +1,201 @@
import os
import random
import subprocess
import re
import time
import json_handler
import verse_handler
import Fonts
import cv2
def create_dirs(output_folder, customer_name, posts=True):
# create a folder for this customer if it doesn't exist
output_path = f"{output_folder}/{customer_name}"
if not os.path.exists(output_path):
os.makedirs(output_path)
# Create folder inside for images
if not os.path.exists(f"{output_path}/verse_images"):
os.makedirs(f"{output_path}/verse_images")
if posts and not os.path.exists(f"{output_path}/post_images"):
os.makedirs(f"{output_path}/post_images")
return output_path
def create_videos(video_folder, audio_folder, json_file, fonts_dir, output_folder, text_source_font, image_file,
customer_name, number_of_videos, fonts: Fonts, posts=True):
run_time_average = 0
if number_of_videos > 1:
start_time_total = time.time()
json_data = json_handler.get_data(json_file)
verses: str = json_data[0]
refs: str = json_data[1]
videos_num = list()
audios_num = list()
fonts_num = list()
# Get lists of video and audio files in the specified folders
video_files = [f"{video_folder}/{file}" for file in os.listdir(video_folder) if file.endswith(".mp4")]
audio_files = [f"{audio_folder}/{file}" for file in os.listdir(audio_folder) if file.endswith(".mp3")]
random_for_video = random.randint(0, len(video_files) - 1)
random_for_audio = random.randint(0, len(audio_files) - 1)
random_for_font = random.randint(0, len(fonts.fonts_path) - 1)
for i in range(number_of_videos):
videos_num.append((random_for_video + i) % len(video_files))
audios_num.append((random_for_audio + i) % len(audio_files))
fonts_num.append((random_for_font + i) % len(fonts.fonts_path))
random.shuffle(videos_num)
random.shuffle(audios_num)
random.shuffle(fonts_num)
# Creating folder for customer
output_path = create_dirs(output_folder, customer_name, posts)
for i in range(number_of_videos):
start_time = time.time()
print(f"Creating Video #{i}")
text_verse = verses[i]
text_source = refs[i]
# Choose a random video file from the list
random_video_num = videos_num[0]
del videos_num[0]
video_file = video_files[random_video_num]
# video_file = f"{video_folder}/30.mp4"
# Choose a random font from list
random_font_num = fonts_num[0]
del fonts_num[0]
font_file = fonts.fonts_path[random_font_num]
font_size = fonts.fonts_size[random_font_num]
font_chars = fonts.fonts_chars_limit[random_font_num]
# Choose a random audio file from the list
random_audio_num = audios_num[0]
del audios_num[0]
audio_file = audio_files[random_audio_num]
# remove chars from versesource for the name
text_source_for_image = text_source.replace(":", "").rstrip('\n')
text_source_for_name = text_source_for_image.replace(' ', '')
file_name = f"/{i}-{text_source_for_name}_{random_video_num}_{random_audio_num}_{random_font_num}.mp4"
create_video(text_verse=text_verse, text_source=text_source, text_source_font=text_source_font,
text_source_for_image=text_source_for_image,
video_file=video_file, audio_file=audio_file, image_file=image_file,
font_file=font_file, font_size=font_size, font_chars=font_chars,
posts=posts,
output_path=output_path, file_name=file_name)
end_time = time.time()
run_time = end_time - start_time
run_time_average += run_time
print(f"\033[0;34m DONE #{i}, Run time:", round(run_time, 2), "seconds! \033[0m", output_path)
if number_of_videos > 1:
run_time_average /= number_of_videos
end_time_total = time.time()
run_time_total = end_time_total - start_time_total
print(f"\n\033[0;32mDone making {number_of_videos} videos for {customer_name}!"
f"\nTotal run time:", round(run_time_total, 2), "seconds!"
f"\nAverage run time:", round(run_time_average, 2),
"seconds = ", round(run_time_average / 60, 2), " minutes! \033[0m")
def create_video(text_verse, text_source, text_source_font, text_source_for_image, video_file, audio_file, image_file,
font_file, font_size, font_chars, output_path, file_name, posts=True):
# Coordinates of logo image and text2 clips
image_y = 1600
text2_y = 1300
# Get the video size
result = subprocess.run(
['ffprobe', '-v', 'error', '-show_entries', 'stream=width,height', '-of', 'csv=p=0:s=x', video_file],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
video_size = re.findall('\d+', result.stdout.decode())[0:2]
video_width, video_height = map(int, video_size)
# Get video duration
ffprobe_command = f'ffprobe -i "{video_file}" -show_entries format=duration -v quiet -of csv="p=0"'
video_duration = subprocess.check_output(ffprobe_command, shell=True)
video_duration = float(video_duration.decode('utf-8').strip())
# Set the start time of text
text_start_time = 1
# Create image of verse
created_verse_image = verse_handler.create_image(text_verse, font_file, font_size, font_chars,
(int(video_width), int(video_height / 2)), output_path,
text_source_for_image)
# fix bug that ':' and beyond wasn't showing on screen
text_source = text_source.replace(':', '\:')
output_path += f"/{file_name}"
# FFMPEG command to overlay images and text onto input video
ffmpeg_command = (f'ffmpeg -y -loop 1 -i "{image_file}" -i "{audio_file}" '
f'-i "{video_file}" -i "{created_verse_image}" -r 24 -filter_complex '
f'"[2:v][0:v]overlay=(W-w)/2:{image_y}[v1]; '
# f'[v1]drawtext=fontfile={selected_font}:text=\'{text_verse}\':x=(w-text_w)/2:y=(h-text_h)/2:fontsize=60:fontcolor=white:'
# f'enable=\'between(t,{text_start_time},{video_duration})\'[v2]; '
f'[v1]drawtext=fontfile=\'{text_source_font}\':text=\'{text_source}\':x=(w-text_w)/2:y={text2_y}:fontsize=42:fontcolor=white:'
f'enable=\'between(t,{text_start_time},{video_duration})\'[v2]; '
f'[v2][3:v]overlay=(W-w)/2:{video_height}/4:enable=\'between(t,{text_start_time},{video_duration})\'[v3]" '
f'-t {video_duration} -map "[v3]" -map 1:a -c:v libx264 -preset veryfast -crf 18 -c:a copy "{output_path}"')
# WITHOUT LOGO
# ffmpeg_command = (f'ffmpeg -y -i "{audio_file}" '
# f'-i "{video_file}" -i "{created_verse_image}" -r 24 -filter_complex '
# # f'[v1]drawtext=fontfile={selected_font}:text=\'{text_verse}\':x=(w-text_w)/2:y=(h-text_h)/2:fontsize=60:fontcolor=white:'
# # f'enable=\'between(t,{text_start_time},{video_duration})\'[v2]; '
# f'"drawtext=fontfile=\'{text_source_font}\':text=\'{text_source}\':x=(w-text_w)/2:y={text2_y}:fontsize=42:fontcolor=white:'
# f'enable=\'between(t,{text_start_time},{video_duration})\'[v1]; '
# f'[v1][2:v]overlay=(W-w)/2:{video_height}/4:enable=\'between(t,{text_start_time},{video_duration})\'[v2]" '
# f'-t {video_duration} -map "[v2]" -map 0:a -c:v libx264 -preset veryfast -crf 18 -c:a copy "{output_path}"')
# Run FFMPEG command
subprocess.call(ffmpeg_command, shell=True)
# if posts:
# verse_handler.create_post_images(video_path=output_path, output_folder=output_path.strip(f"/{file_name}"),
# verse_image_path=created_verse_image, text_source=text_source)
def create_post_images(video_path: str, verse_image_path, text_source, output_folder):
# Open the video file
video = cv2.VideoCapture(video_path)
# Get the frame rate of the video
fps = int(video.get(cv2.CAP_PROP_FPS))
# Set the time in seconds to extract a frame from
time_in_seconds = 2
# Calculate the frame index to extract
frame_index = time_in_seconds * fps
# Set the output image size
output_size = (1080, 1080)
# Loop through the video frames until we reach the desired frame
for i in range(frame_index):
ret, frame = video.read()
# Crop the middle square of the frame
height, width, channels = frame.shape
y = 325
cropped_frame = frame[y:y + 1440, 0:width]
# Resize the cropped frame to the output size
# resized_frame = cv2.resize(cropped_frame, output_size)
# Save the frame as an image
output_name = video_path.split('/')
output_name = output_name[len(output_name) - 1].strip(".mp4")
cv2.imwrite(f"{output_folder}/post_images/{output_name}.jpg", cropped_frame)
# Release the video file
video.release()

50
helper_images.py Normal file
View File

@@ -0,0 +1,50 @@
from PIL import Image, ImageEnhance
import os
def darken_images(images_folder, output_folder):
# Set desired darkness
dark = 0.5
# Loop through all the images in the directory
for filename in os.listdir(images_folder):
if filename.endswith(".jpg") or filename.endswith(".png"):
# Open the image
filepath = os.path.join(images_folder, filename)
img = Image.open(filepath)
# Create an enhancer object for the image
enhancer = ImageEnhance.Brightness(img)
# Reduce the brightness by a factor of 'dark'
dark_img = enhancer.enhance(dark)
# Save the cropped image
dark_img.save(f"{output_folder}/{filename}")
def cut_images(images_folder, output_folder):
# Set the target size
target_size = (1080, 1350)
# Loop through all the images in the directory
for filename in os.listdir(images_folder):
if filename.endswith(".jpg") or filename.endswith(".png"):
# Open the image
filepath = os.path.join(images_folder, filename)
img = Image.open(filepath)
# Get the size of the image
width, height = img.size
# Calculate the coordinates for cropping
left = (width - target_size[0]) // 2
top = (height - target_size[1]) // 2
right = left + target_size[0]
bottom = top + target_size[1]
# Crop the image
img = img.crop((left, top, right, bottom))
# Save the cropped image
img.save(f"{output_folder}/{filename}")

9
json_handler.py Normal file
View File

@@ -0,0 +1,9 @@
import json
def get_data(json_file):
with open(f'{json_file}', 'r', encoding='utf-8') as f:
jsonData = json.load(f)
verses: str = jsonData['verses']
refs: str = jsonData['references']
return verses, refs

19
main.py Normal file
View File

@@ -0,0 +1,19 @@
import post_handler
import helper_images
# Define the paths and values to everything
number_of_posts = 2
images_folder = "C:/Bots/ChristianPostMaker/sources/images/cropped/darken"
text_file = "C:/Bots/ChristianPostMaker/sources/quotes.txt"
font_dir = "C:/Users/samla/AppData/Local/Microsoft/Windows/Fonts/MouldyCheeseRegular-WyMWG.ttf"
output_folder = "C:/Bots/ChristianPostMaker/customers"
logo_file = "C:/Bots/ChristianPostMaker/sources/logo.png"
customer_name = "test1"
if __name__ == "__main__":
# helper_images.cut_images(images_folder, f"{images_folder}/cropped")
# helper_images.darken_images(images_folder, f"{images_folder}/darken")
post_handler.create_posts(images_folder=images_folder, text_file=text_file,
font_dir=font_dir, output_folder=output_folder,
logo_file=logo_file, customer_name=customer_name, number_of_posts=number_of_posts)

143
post_handler.py Normal file
View File

@@ -0,0 +1,143 @@
import os
import random
import textwrap
import time
from string import ascii_letters
from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageEnhance
import json_handler
def create_dirs(output_folder, customer_name):
# create a folder for this customer if it doesn't exist
output_path = f"{output_folder}/{customer_name}"
if not os.path.exists(output_path):
os.makedirs(output_path)
# Create folder inside for images
if not os.path.exists(f"{output_path}/verse_images"):
os.makedirs(f"{output_path}/verse_images")
return output_path
def create_posts(images_folder, text_file, font_dir, output_folder, customer_name, number_of_posts, logo_file: str = None):
run_time_average = 0
if number_of_posts > 1:
start_time_total = time.time()
# json_data = json_handler.get_data(json_file)
# verses: str = json_data[0]
# refs: str = json_data[1]
quotes = ["test1", "test2"]
# Get list of photos in the specified folder and shuffle it
image_num = list()
image_files = [f"{images_folder}/{file}" for file in os.listdir(images_folder) if file.endswith(".jpg") or file.endswith(".png")]
random_for_image = random.randint(0, len(image_files) - 1)
for i in range(number_of_posts):
image_num.append((random_for_image + i) % len(image_files))
random.shuffle(image_num)
# Creating folder for customer
output_path = create_dirs(output_folder, customer_name)
for i in range(number_of_posts):
start_time = time.time()
print(f"Creating Post #{i}")
text = quotes[i]
# Choose a random image file from the list
random_image_num = image_num[0]
del image_num[0]
image_file = image_files[random_image_num]
file_name = f"/{i}-{random_image_num}.jpg"
create_post(image_file=image_file, text=text,
font_dir=font_dir, output_path=output_path, file_name=file_name,
logo_file=logo_file, customer_name=customer_name)
end_time = time.time()
run_time = end_time - start_time
run_time_average += run_time
print(f"\033[0;34m DONE #{i}, Run time:", round(run_time, 2), "seconds! \033[0m", output_path)
if number_of_posts > 1:
run_time_average /= number_of_posts
end_time_total = time.time()
run_time_total = end_time_total - start_time_total
print(f"\n\033[0;32mDone making {number_of_posts} posts for {customer_name}!"
f"\nTotal run time:", round(run_time_total, 2), "seconds!"
f"\nAverage run time:", round(run_time_average, 2),
"seconds = ", round(run_time_average / 60, 2), " minutes! \033[0m")
def create_post(image_file, text, font_dir, output_path, file_name, logo_file, customer_name):
# Open specific image
img = Image.open(image_file)
# Load selected font
font = ImageFont.truetype(font=f'{font_dir}', size=75)
# Create DrawText object
draw = ImageDraw.Draw(im=img)
# Define our text:
# Calculate the average length of a single character of our font.
# Note: this takes into account the specific font and font size.
avg_char_width = sum(font.getsize(char)[0] for char in ascii_letters) / len(ascii_letters)
# Translate this average length into a character count
max_char_count = int(img.size[0] * .718 / avg_char_width)
# Create a wrapped text object using scaled character count
new_text = textwrap.fill(text=text, width=max_char_count)
# Define the positions of logo and text
x_logo = 0
y_logo = 1100
x_text = img.size[0] / 2
y_text = img.size[1] / 2
position = (x_text, y_text)
# Draw the shadow text
shadow_color = (0, 0, 0, 128)
shadow_position = (x_text+5, y_text+5)
draw.text(shadow_position, text, font=font, fill=shadow_color, anchor='mm')
# Add main text to the image
draw.text(position, text=new_text, font=font, fill=(255, 255, 255, 255), anchor='mm',
align='center')
if logo_file is not None:
# Open logo file
img_logo = Image.open(logo_file)
# Reduce the alpha of the overlay image by 50%
alpha = 0.5
enhancer = ImageEnhance.Brightness(img_logo)
img_logo_darken = enhancer.enhance(alpha)
# Create a new image object with the same size as the background image
img_with_logo = Image.new('RGBA', img.size, (0, 0, 0, 0))
# Draw the background image onto the new image
img_with_logo.paste(img, (0, 0))
# Draw the overlay image onto the new image
img_with_logo.paste(img_logo_darken, (int(x_logo), int(y_logo)), mask=img_logo_darken)
# Convert from RGBA to RGB
img_with_logo_rgb = img_with_logo.convert("RGB")
# Save the image
img_with_logo_rgb.save(f"{output_path}/{file_name}")
# combined.show()
return f"{output_path}/{file_name}"
# If logo was off
# Save the image
img.save(f"{output_path}/{file_name}")
# combined.show()
return f"{output_path}/{file_name}"

120
sources/ChristianQuotes.txt Normal file
View File

@@ -0,0 +1,120 @@
Don't worry about the future.
This is the day that the LORD has made.
Believe your prayers will be answered.
Everyday is a gift from God.
Where the Spirit of the Lord is, there is freedom.
When you stress it, pray about it.
Thank you God for another day.
At the right time, I, the Lord, will make it happen.
God says you are more than a conqueror.
Go to God first.
I can do all things through Him who strengthens me.
God's word never fails.
God is greater than your fears.
God is greater than the highs and lows.
He is risen.
God's ways > my ways
No prayer is too small for God.
I am not lucky, I am blessed.
I will refresh the weary and satisfy the faint.
Jesus loves you on your bad days too.
With God all things are possible.
Put your trust in the one who holds it all.
Keep God first.
God, thank you.
God is always on time.
God heard you. Be patient.
Thank God before it happens.
God will never let you down.
Jesus heals.
God is patient with you.
I will strengthen you and help you.
God makes no mistakes.
Love never fails.
I have hidden your word in my heart.
Always be joyful. Never stop praying.
Don't worry about the future.
Less on me, more of him.
Focus on God.
God has a plan.
God is with you.
Jesus changes everything.
My future is in God's hands.
God is for you.
Lord, guide me in every situation.
God is fighting for you.
Don't forget to pray today.
Pray in the good times too.
Every word of God proves true.
God so loved.
Be anxious for nothing.
One prayer can do a lot.
Lord, guide me.
Abide in Him.
God's plan is worthy waiting for.
Choose worship over worry.
God is always with you.
God's plan, not mine.
Prayer is a relationship with God.
When you wake up, pray.
Give it to God.
Jesus is the permanent fix to our problems.
God is able.
You have to let God handle it.
God listens when you pray.
Never get tired of doing good.
When everything else fails. God doesn't.
Set you minds on things above.
God keeps his promises.
You are never too lost to be found.
In His presence there is fullness of joy.
Let my life be an example.
Love casts out fear.
The LORD confides in those who fear him.
Quit overthinking and just pray.
Give God your weakness and He will give you His strength.
In him you have peace.
Trust God when he tells you to wait.
God knows everything and still he listens.
Jesus, I am all in.
God has a purpose for your life.
He turns my darkness into light.
The joy of the Lord is my strength.
God, I pray that I would draw closer to you.
Your comfort broughts joy to my soul.
God loves you unconditionally.
God hears your prayer. Trust him timing.
In you, LORD my God, I put my trust.
For no word from God will every fail.
Worry doesn't change anything. Prayer does.
Faith, Hope, Love.
Keep praying as you wait.
Reminder: God forgave you.
God has given you a spirit of power, of love and of a sound mind.
God has not given us a spirit of fear.
You are my defender, my place of safety in times of troubles.
We love because He first loved us.
Even when you are frustrated, seek God.
God is faithful.
God is all we need.
Lord, I can't do this on my own.
Walk by faith, not by sight.
Being a Christian doesn't change what you deal with. It changes how you deal with it.
In my weakness, you give me strength.
I will refresh the weary and satisfy the faint.
Anxiety comes from the world, peace comes from God.
If God's for you, It doesn't matter what's against you.
The Way, The Truth, The Life
God is most glorified in us when we are most satisfied in Him.
True faith means putting every hope in God's fidelity to His Promises.
Faith does not eliminate questions. But faith knows where to take them.
Some of God's greatest gifts are unanswered prayers.
What God intended for you goes far beyond anything you can imagine.
Life is God's novel. Let him write it.
Your word is a lamp to my feet and a light for my path.
Let us rejoice and be glad in the Lord.
Fear ends where faith begins.
God is my first priority.
Amazing grace.
What would Jesus do?
My lifeguard walked on water.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

BIN
sources/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
sources/logo.psd Normal file

Binary file not shown.

117
verse_handler.py Normal file
View File

@@ -0,0 +1,117 @@
import os
from string import ascii_letters
import cv2
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import textwrap
def create_image(text, font_path, font_size, max_char_count, image_size, save_path, text_source):
save_path += "/verse_images"
text = fix_fonts(text, font_path)
# Open a blank image
img = Image.new('RGBA', image_size, color=(190, 190, 190, 0))
# Load selected font
font = ImageFont.truetype(font=f'{font_path}', size=font_size)
# Create DrawText object
draw = ImageDraw.Draw(im=img)
# Define our text:
# Calculate the average length of a single character of our font.
# Note: this takes into account the specific font and font size.
avg_char_width = sum(font.getsize(char)[0] for char in ascii_letters) / len(ascii_letters)
# Translate this average length into a character count
max_char_count = max(int(img.size[0] * .718 / avg_char_width), max_char_count)
# Create a wrapped text object using scaled character count
new_text = textwrap.fill(text=text, width=max_char_count)
# Draw the shadow text
shadow_image = Image.new('RGBA', img.size, color=(255, 255, 255, 0))
shadow_draw = ImageDraw.Draw(im=shadow_image)
shadow_draw.text(xy=(img.size[0] / 2 - 1, img.size[1] / 2 + 4), text=new_text, font=font, fill=(0, 0, 0, 80), anchor='mm',
align='center')
# Add main text to the image
draw.text(xy=(img.size[0] / 2, img.size[1] / 2), text=new_text, font=font, fill=(255, 255, 255, 255), anchor='mm',
align='center')
# combine shadow and main
combined = Image.alpha_composite(shadow_image, img)
# check if image of this source (bible reference) exists already
path_to_check = f"{save_path}/{text_source}.png"
i = 1
while os.path.exists(path_to_check):
path_to_check = f"{save_path}/{text_source}-{i}.png"
i += 1
# Save the image
combined.save(f"{path_to_check}")
# combined.show()
return f"{path_to_check}"
def create_post_images(video_path: str, verse_image_path, text_source, output_folder):
# Open the video file
video = cv2.VideoCapture(video_path)
# Get the frame rate of the video
fps = int(video.get(cv2.CAP_PROP_FPS))
# Set the time in seconds to extract a frame from
time_in_seconds = 2
# Calculate the frame index to extract
frame_index = time_in_seconds * fps
# Set the output image size
output_size = (1080, 1080)
# Loop through the video frames until we reach the desired frame
for i in range(frame_index):
ret, frame = video.read()
# Crop the middle square of the frame
height, width, channels = frame.shape
y = int((height - width) / 2)
cropped_frame = frame[y:y+1080, 0:width]
background = Image.fromarray(cropped_frame)
verse = Image.open(verse_image_path)
combined = Image.blend(background, verse, 1)
# Create a drawing object
draw = ImageDraw.Draw(combined)
# Define the text to add and the font to use
text = 'Hello, World!'
font = ImageFont.truetype(r"C\:/Users/Samurai/AppData/Local/Microsoft/Windows/Fonts/Aloevera-OVoWO.ttf", size=36)
# Determine the position to place the text
text_width, text_height = draw.textsize(text, font=font)
x = (combined.width - text_width) / 2
y = 1300
# Add the text to the image
draw.text((x, y), text, font=font, fill=(255, 255, 255))
output_name = video_path.split('/')
output_name = output_name[len(output_name) - 1].strip(".mp4")
combined.save(f"{output_folder}/post_images/{output_name}.jpg")
# Save the frame as an image
# output_name = video_path.split('/')
# output_name = output_name[len(output_name) - 1].strip(".mp4")
# cv2.imwrite(f"{output_folder}/post_images/{output_name}.jpg", cropped_frame)
#
# Release the video file
video.release()
def fix_fonts(text, font):
# Font 6 can't display '
if (font.__contains__("FlowersSunday")):
return text.replace("'", "")
return text