Fix video export folder, add license, use Tuffy font

This commit is contained in:
ABelliqueux 2024-02-18 18:39:59 +01:00
parent a19f713d16
commit eb49b32940
2 changed files with 40 additions and 22 deletions

BIN
Tuffy_Bold.ttf Normal file

Binary file not shown.

View File

@ -1,4 +1,26 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
#
# main_c.py
#
# v0.1 - 2024 schnappy <contact@schnappy.xyz>
#
# The Tuffy font is public domain and was created by
# Thatcher Ulrich <tu@tulrich.com> http://tulrich.com
# Karoly Barta bartakarcsi@gmail.com
# Michael Evans http://www.evertype.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A full copy of the GNU General Public License is available from
# https://www.gnu.org/licenses/gpl-3.0.en.html
# #
import collections import collections
import gettext import gettext
@ -37,6 +59,7 @@ from send2trash import send2trash
# X Import config values from config file # X Import config values from config file
# X Translation # X Translation
# o Better settings names # o Better settings names
# o Allow opening and exporting without a camera connected
running_from_folder = os.path.realpath(__file__) running_from_folder = os.path.realpath(__file__)
alphabet = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'] alphabet = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
@ -85,13 +108,11 @@ for location in config_locations:
camera_settings = project_settings['CHECK'] camera_settings = project_settings['CHECK']
config_found_msg = _("Found configuration file in {}").format(os.path.expanduser(location)) config_found_msg = _("Found configuration file in {}").format(os.path.expanduser(location))
print(config_found_msg) print(config_found_msg)
# TODO : Check resulting config has needed settings, fill missing ones
class KISStopmo(tk.Tk): class KISStopmo(tk.Tk):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
self.check_config() self.check_config()
print(project_settings)
# Default config # Default config
# Set script settings according to config file # Set script settings according to config file
self.onion_skin = project_settings['onion_skin_onstartup'] self.onion_skin = project_settings['onion_skin_onstartup']
@ -132,7 +153,7 @@ class KISStopmo(tk.Tk):
self.img_list = {} self.img_list = {}
self.img_list = self.get_frames_list(self.savepath) self.img_list = self.get_frames_list(self.savepath)
self.img_index = self.check_range(len(self.img_list)-1, False) self.img_index = self.check_range(len(self.img_list)-1, False)
self.splash_text = 'Stopmo!' self.splash_text = _("No images yet! Start shooting...")
# Camera setup # Camera setup
self.camera = gp.check_result(gp.gp_camera_new()) self.camera = gp.check_result(gp.gp_camera_new())
try: try:
@ -143,8 +164,8 @@ class KISStopmo(tk.Tk):
if self.check_status(self.camera, self.current_camera_config) is False: if self.check_status(self.camera, self.current_camera_config) is False:
print(_("Warning: Some settings are not set to the recommended value!")) print(_("Warning: Some settings are not set to the recommended value!"))
except: except:
self.splash_text = _("Camera not found or busy.") self.splash_text += _("\nCamera not found or busy.")
self.timeout = 3000 # milliseconds self.timeout = 3000 # milliseconds
self.splashscreen = self.generate_splashscreen() self.splashscreen = self.generate_splashscreen()
@ -159,7 +180,7 @@ class KISStopmo(tk.Tk):
self.label.configure(image=photo) self.label.configure(image=photo)
self.label.image = photo self.label.image = photo
if project_settings['trigger_mode'] == 'event': if project_settings['trigger_mode'] == 'event':
root.after(1000, self.trigger_bg_loop) root.after(1000, self.trigger_bg_loop)
# ~ root.after(1000, self.wait_for_capture) # ~ root.after(1000, self.wait_for_capture)
@ -197,19 +218,16 @@ class KISStopmo(tk.Tk):
def generate_splashscreen(self): def generate_splashscreen(self):
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
from io import BytesIO from io import BytesIO
img = Image.new('RGB', (self.screen_w, self.screen_h), (128,128,128)) splash = Image.new('RGB', (self.screen_w, self.screen_h), (200,200,200))
d = ImageDraw.Draw(img) splash_draw = ImageDraw.Draw(splash)
if self.splash_text is not None: if self.splash_text is not None:
fnt = ImageFont.truetype("FreeMono", 50) font = ImageFont.truetype("Tuffy_Bold.ttf", 60)
fnt_len = fnt.getlength(self.splash_text) font_len = font.getlength(self.splash_text)
d.text((self.screen_w/2 - fnt_len/2, self.screen_h/2 ), self.splash_text, fill=(255, 0, 0), font=fnt) splash_draw.text((self.screen_w/2 - font_len/2, self.screen_h/2 ), self.splash_text, fill=(255, 255, 255), font=font)
# Save to file
# img.save('test.png')
# Use in-memory # Use in-memory
s = BytesIO() splash_bytes = BytesIO()
img.save(s, 'png') splash.save(splash_bytes, 'png')
# ~ return s.getvalue() return splash
return img
def find_letter_after(self, letter:str): def find_letter_after(self, letter:str):
@ -301,7 +319,7 @@ class KISStopmo(tk.Tk):
existing_animation_files = self.img_list existing_animation_files = self.img_list
# ~ existing_animation_files = # ~ existing_animation_files =
file_list = os.listdir(folder) file_list = os.listdir(folder)
print(file_list) # ~ print(file_list)
for file in file_list: for file in file_list:
if (file.startswith(self.project_letter) and file.endswith(project_settings['file_extension'])): if (file.startswith(self.project_letter) and file.endswith(project_settings['file_extension'])):
if file not in existing_animation_files: if file not in existing_animation_files:
@ -621,7 +639,7 @@ class KISStopmo(tk.Tk):
next_filename = self.return_next_frame_number(self.get_last_frame(self.savepath)) next_filename = self.return_next_frame_number(self.get_last_frame(self.savepath))
# build full path to file # build full path to file
target_path = os.path.join(self.savepath, next_filename) target_path = os.path.join(self.savepath, next_filename)
print(target_path) # ~ print(target_path)
# Get file from camera # Get file from camera
if event_data is None: if event_data is None:
# ~ print("j pressed") # ~ print("j pressed")
@ -636,7 +654,7 @@ class KISStopmo(tk.Tk):
event_data.folder, event_data.name, gp.GP_FILE_TYPE_NORMAL) event_data.folder, event_data.name, gp.GP_FILE_TYPE_NORMAL)
new_frame.save(target_path) new_frame.save(target_path)
# ~ next_filename = prefix+next(filename)+ext # ~ next_filename = prefix+next(filename)+ext
print(self.img_list) # ~ print(self.img_list)
if '{letter}.-001.JPG'.format(letter=self.project_letter) in self.img_list: if '{letter}.-001.JPG'.format(letter=self.project_letter) in self.img_list:
# ~ self.img_list.pop('A.-001.JPG') # ~ self.img_list.pop('A.-001.JPG')
self.img_list.pop('{letter}.-001.JPG'.format(letter=self.project_letter)) self.img_list.pop('{letter}.-001.JPG'.format(letter=self.project_letter))
@ -674,8 +692,8 @@ class KISStopmo(tk.Tk):
def trigger_export_animation(self, event): def trigger_export_animation(self, event):
output_folder = filedialog.askdirectory() output_folder = filedialog.askdirectory()
output_folder = "{folder}{sep}{filename}".format(folder=output_folder, sep=os.sep, filename=self.output_filename) self.output_filename = "{folder}{sep}{filename}".format(folder=output_folder, sep=os.sep, filename=self.output_filename)
print(_("Exporting to {}").format(output_folder)) print(_("Exporting to {}").format(self.output_filename))
self.export_task = asyncio.run(self.export_animation()) self.export_task = asyncio.run(self.export_animation())
# check with self.export_task.done() == True ? https://stackoverflow.com/questions/69350645/proper-way-to-retrieve-the-result-of-tasks-in-asyncio # check with self.export_task.done() == True ? https://stackoverflow.com/questions/69350645/proper-way-to-retrieve-the-result-of-tasks-in-asyncio