diff --git a/modules/ui.py b/modules/ui.py index 6ce27ae..8647017 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -25,6 +25,7 @@ from modules.utilities import ( has_image_extension, ) +modules.globals.face_opacity = 100 os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" os.environ["QT_SCREEN_SCALE_FACTORS"] = "1" os.environ["QT_SCALE_FACTOR"] = "1" @@ -970,36 +971,68 @@ def webcam_preview(root: ctk.CTk): create_source_target_popup_for_webcam(root, modules.globals.souce_target_map) +# Add this function to update the opacity value +def update_opacity(value): + modules.globals.face_opacity = int(value) + + +# Modify the create_webcam_preview function to include the slider def create_webcam_preview(): - global preview_label, PREVIEW, opacity_slider + global preview_label, PREVIEW camera = cv2.VideoCapture(0) camera.set(cv2.CAP_PROP_FRAME_WIDTH, PREVIEW_DEFAULT_WIDTH) camera.set(cv2.CAP_PROP_FRAME_HEIGHT, PREVIEW_DEFAULT_HEIGHT) camera.set(cv2.CAP_PROP_FPS, 60) - preview_label.configure(width=PREVIEW_DEFAULT_WIDTH, height=PREVIEW_DEFAULT_HEIGHT) - PREVIEW.deiconify() - frame_processors = get_frame_processors_modules(modules.globals.frame_processors) + # Remove any existing widgets in PREVIEW window + for widget in PREVIEW.winfo_children(): + widget.destroy() - source_image = None + # Create a main frame to hold all widgets + main_frame = ctk.CTkFrame(PREVIEW) + main_frame.pack(fill="both", expand=True) + + # Create a frame for the preview label + preview_frame = ctk.CTkFrame(main_frame) + preview_frame.pack(fill="both", expand=True, padx=10, pady=10) + + preview_label = ctk.CTkLabel(preview_frame, text="") + preview_label.pack(fill="both", expand=True) + + # Create a frame for the slider + slider_frame = ctk.CTkFrame(main_frame) + slider_frame.pack(fill="x", padx=10, pady=(0, 10)) + + opacity_label = ctk.CTkLabel(slider_frame, text="Face Opacity:") + opacity_label.pack(side="left", padx=(0, 10)) - # Create opacity slider opacity_slider = ctk.CTkSlider( - PREVIEW, + slider_frame, from_=0, to=100, - number_of_steps=10, # Increment by 10 - command=lambda value: setattr(modules.globals, "opacity", int(value)), + number_of_steps=10, + command=update_opacity, fg_color=("gray75", "gray25"), progress_color=("DodgerBlue", "DodgerBlue"), button_color=("DodgerBlue", "DodgerBlue"), button_hover_color=("RoyalBlue", "RoyalBlue"), ) - opacity_slider.pack(fill="x", padx=20, pady=(0, 10)) - opacity_slider.set(100) # Default opacity is 100 (fully opaque) + opacity_slider.pack(side="left", fill="x", expand=True) + opacity_slider.set(modules.globals.face_opacity) + + frame_processors = get_frame_processors_modules(modules.globals.frame_processors) + + source_image = None + + def update_frame_size(event): + nonlocal temp_frame + if modules.globals.live_resizable: + temp_frame = fit_image_to_size(temp_frame, event.width, event.height) + + preview_frame.bind("", update_frame_size) while camera: ret, frame = camera.read() @@ -1011,32 +1044,31 @@ def create_webcam_preview(): if modules.globals.live_mirror: temp_frame = cv2.flip(temp_frame, 1) - if modules.globals.live_resizable: - temp_frame = fit_image_to_size( - temp_frame, PREVIEW.winfo_width(), PREVIEW.winfo_height() - ) - if not modules.globals.map_faces: if source_image is None and modules.globals.source_path: source_image = get_one_face(cv2.imread(modules.globals.source_path)) + original_frame = temp_frame.copy() for frame_processor in frame_processors: temp_frame = frame_processor.process_frame(source_image, temp_frame) + + # Apply opacity + opacity = modules.globals.face_opacity / 100 + temp_frame = cv2.addWeighted( + temp_frame, opacity, original_frame, 1 - opacity, 0 + ) else: modules.globals.target_path = None for frame_processor in frame_processors: temp_frame = frame_processor.process_frame_v2(temp_frame) - # Apply opacity blending (if needed) - if modules.globals.opacity < 100: - alpha = modules.globals.opacity / 100.0 - temp_frame = cv2.addWeighted(frame, 1 - alpha, temp_frame, alpha, 0) - image = cv2.cvtColor(temp_frame, cv2.COLOR_BGR2RGB) image = Image.fromarray(image) image = ImageOps.contain( - image, (temp_frame.shape[1], temp_frame.shape[0]), Image.LANCZOS + image, + (preview_frame.winfo_width(), preview_frame.winfo_height()), + Image.LANCZOS, ) image = ctk.CTkImage(image, size=image.size) preview_label.configure(image=image) @@ -1048,9 +1080,6 @@ def create_webcam_preview(): camera.release() PREVIEW.withdraw() - # Remove opacity slider when webcam preview is closed - opacity_slider.pack_forget() - def create_source_target_popup_for_webcam(root: ctk.CTk, map: list) -> None: global POPUP_LIVE, popup_status_label_live