Compare commits

..

No commits in common. "insert" and "gphoto" have entirely different histories.

2 changed files with 27 additions and 54 deletions

View File

@ -53,7 +53,6 @@ project_settings_defaults = {
'export_options' : 'scale=1920:-1,crop=1920:1080:0:102',
}
# TODO: replace hflip+vflip with flip option
camera_current_settings_defaults = {
'cam_w' : 800,
'cam_h' : 600,
@ -105,7 +104,6 @@ class webcam():
self.overlay = None
# Original frame for saving
self.og_frame = None
self.flip_img = bool(camera_settings['vflip'] or camera_settings['hflip'] )
self.onionskin = project_settings['onion_skin_onstartup']
self.onionskin_was_on = self.onionskin
self.liveview_only = False
@ -134,12 +132,10 @@ class webcam():
if not ret:
print(_("Failed to grab frame."))
return False
if self.flip_img:
overlay = cv2.flip(overlay, -1)
# Keep original pic in memory
self.og_frame = overlay.copy()
# Resize preview to fit screen
overlay = cv2.resize(overlay, (project_settings['screen_w'], project_settings['screen_h']))
# Keep original pic in memory
self.og_frame = overlay.copy()
if self.liveview_only:
# Don't mix it
self.frame = overlay
@ -216,7 +212,8 @@ class webcam():
return self.camera_current_settings
def flip_image(self):
self.flip_img = not self.flip_img
self.frame = cv2.flip(self.frame, -1)
self.og_frame = cv2.flip(self.og_frame, -1)
def focus(self, direction:str='-'):
self.apply_setting(['lenspos'], 1)
@ -332,10 +329,10 @@ class picam():
# Same as in webcam() class
def capture_preview(self):
overlay = self.cam.capture_array("main")
# Keep original pic in memory
self.og_frame = overlay.copy()
# Resize preview to fit screen
overlay = cv2.resize(overlay, (project_settings['screen_w'], project_settings['screen_h']))
# Keep original pic in memory
self.og_frame = overlay.copy()
if self.liveview_only:
# Don't mix it
self.frame = overlay
@ -451,7 +448,7 @@ class dslr():
self.onionskin_was_on = self.onionskin
self.liveview_only = False
self.lenspos = None
self.flip_img = bool(camera_settings['vflip'] or camera_settings['hflip'] )
self.flip_img = False
self.cam_busy = False
self.camera_current_config = None
self.cam = self.init_camera()
@ -476,6 +473,7 @@ class dslr():
pass
def find_file_ext(self, gp_name:str, full_path:str):
# TODO: use re to sub png with jpg ?
# extract dir path
dirname = os.path.dirname(full_path)
# extract filename from path
@ -501,6 +499,7 @@ class dslr():
if self.cam is None:
self.cam = self.init_camera()
if not self.cam_busy:
# CHECK: Should we init and close dslr for each frame ?
# Check battery level
battery_level = int(self.check_status_value(self.camera_current_config, 'batterylevel')[:-1])
if battery_level < 10:
@ -533,7 +532,6 @@ class dslr():
return False
# Flip image if needed
if self.flip_img:
# Re-open filen flip and save
frm = cv2.imread(img_path)
frm = cv2.flip(frm, -1)
cv2.imwrite(img_path, frm)
@ -604,7 +602,7 @@ class dslr():
return status
def flip_image(self):
self.flip_img = not self.flip_img
self.flip_img = True
def focus(self, direction:str='-'):
if direction == '-':
@ -618,6 +616,7 @@ class dslr():
self.camera_current_config = self.gp.check_result(self.gp.gp_camera_get_config(self.cam))
for setting in self.camera_current_settings:
self.camera_current_settings[setting]['value'] = self.camera_current_settings[setting]['default']
# TODO: use self.apply_setting() instead
self.apply_gphoto_setting(setting)
status = self.gp.check_result(self.gp.gp_camera_set_config(self.cam, self.camera_current_config))
@ -801,8 +800,15 @@ def get_frames_list(folder:str):
def get_frame_by_idx(folder:str, index:int):
# Refresh file list
existing_animation_files = get_frames_list(folder)
# Get last file
# Filename pattern is A.0001.JPG
return existing_animation_files[index].split('.')
if index and index in range(len(existing_animation_files)):
frm = cv2.imread(os.path.join(folder, existing_animation_files[index]))
frm = cv2.resize(frm, (project_settings['screen_w'], project_settings['screen_h']))
return frm
else:
return generate_text_image(_("Image not found."), project_settings['screen_w'], project_settings['screen_h'])
def get_last_frame(folder:str):
# Refresh file list
@ -820,11 +826,8 @@ def get_before_last_frame(folder:str):
return existing_animation_files[-2]
def get_onionskin_frame(folder:str, index:int=-1):
if index == -1:
prev_image = get_last_frame(folder)
else:
prev_image = get_frame_by_idx(folder, index)
def get_onionskin_frame(folder:str):
prev_image = get_last_frame(folder)
prev_image = '.'.join(prev_image)
if os.path.exists(os.path.expanduser(os.path.join(savepath, prev_image))):
frm = cv2.imread(os.path.join(savepath, prev_image))
@ -910,18 +913,6 @@ def batch_rename(folder:str):
return get_frames_list(folder)
def batch_rename_reversed(folder:str, from_index:int=0):
# initialize counter to 0
frame_list = get_frames_list(os.path.realpath(folder))
print(frame_list[from_index:])
counter = (".%04i." % x for x in count(len(frame_list), -1))
for i in reversed(frame_list[from_index:]):
if os.path.exists(os.path.join(folder, i)):
cnt = next(counter)
os.rename(os.path.join(folder, i), os.path.join(folder, "{}{}{}".format(project_letter, cnt, project_settings['file_extension'])))
return get_frames_list(folder)
def offset_dictvalues(from_index=0):
dict_copy = dict(img_list)
for i in range(from_index, len(dict_copy)):
@ -954,19 +945,6 @@ def remove_frame(img_list:list, img_index:int):
else:
return img_list, 0, blank_image
def insert_frame(img_list:list, frame_name:str, img_index:int):
if len(img_list) > img_index:
folder_path = os.path.realpath(savepath)
# ~ frame_name = img_list[img_index]
frame_path = os.path.join(folder_path, frame_name)
# ~ if not os.path.exists(frame_path):
# ~ return img_list, img_index, blank_image
print(_("Inserting {}").format(frame_path))
# rename files and get new list
img_list = batch_rename_reversed(folder_path, img_index+1)
return img_list, img_index
else:
return img_list, 0
def testDevice(source):
cap = cv2.VideoCapture(source)
@ -1177,12 +1155,7 @@ def main(args):
# SPACE or numpad 0 pressed
elif (k%256 == 32) or (k%256 == 48) or (k%256 == 176):
print(_("Capture frame"))
# ~ img_name = return_next_frame_number(get_last_frame(savepath))
img_name = return_next_frame_number(img_list[index].split('.'))
if img_name in img_list:
insert_frame(img_list, img_name, index)
else:
img_name = return_next_frame_number(get_last_frame(savepath))
img_name = return_next_frame_number(get_last_frame(savepath))
img_path = os.path.join(savepath, img_name)
capture_ok = cam.capture_frame(img_path)
if capture_ok:
@ -1191,8 +1164,9 @@ def main(args):
if len(img_list) and (img_list[index] == '{letter}.-001.{ext}'.format(letter=project_letter, ext=project_settings['file_extension'])):
img_list[index] = img_name
else:
index += 1
cam.frame = get_onionskin_frame(savepath, index)
# Move to last frame
index = len(img_list)
cam.frame = get_onionskin_frame(savepath)
cam.o_frame = cam.frame.copy()
else:
print(_("Error during capture. Try again."))

View File

@ -20,7 +20,7 @@ Encore une fois, l'objectif est de créer un logiciel simple et minimaliste dans
* Pilotage de certains réglages de la caméra depuis la télécommande/clavier (balance des blancs, rotation de l'image, mise au point (picam V3), exposition...)
* Prévisualisation de l'animation
* Exportation vidéo avec [ffmpeg](https://ffmpeg.org/)
* Textes localisés (anglais et français disponible pour le moment.)
* Interface localisée (anglais et français disponible pour le moment.)
## Banc de test
@ -44,7 +44,6 @@ Des fonctions supplémentaires sont prévues :
* Mise à jour de la traduction FR
* Réflexe numérique: utilisation du liveview de l'appareil (si je trouve un modèle compatible pour le développement)
* Mécanisme de mise à jour
## Contributions
@ -65,7 +64,7 @@ Dans un terminal :
3. Aller dans répertoire du projet : `cd stopi2`
4. Créer un environnement virtuel (venv) Python : `python -m venv ./`
- Mise à jour de l'environnement pypi: '`MAKEFLAGS="-j$(nproc)" pip install -vvv --upgrade pip setuptools wheel`
- (Optionnel) Dans le cas de l'utilisation d'une "raspicam", il faudra ajouter le paramètre `--system-site-packages` à la commande de création de l'environnement virtuel pour avoir accès au module picamera2 du système, et installer la librairie correspondante `python3-picamera2`.
- (Optionnel) Dans le cas de l'utilisation d'une "raspicam", il faudra ajouter le paramètre `--system-site-packages` pour avoir accès au module picamera2, et installer la librairie correspondante `python3-picamera2`.
5. Activer l'environnement virtuel avec `source bin/activate`
6. Installer les dépendances python (~150Mo) : `MAKEFLAGS="-j$(nproc)" pip install -r requirements.txt`
7. Activer l'éxécution du script : `chmod +x stopi2.sh`