Compare commits

...

5 Commits

Author SHA1 Message Date
Justin Lacy 6208736d73
Merge 4d23db47e2 into 7f95b69bc5 2024-08-23 13:59:37 -07:00
Vic P. 7f95b69bc5
Add TODO to README.md 2024-08-24 00:45:14 +07:00
Justin Lacy 4d23db47e2
fix: use string strip() function to remove braces
in drag-and-drop file path
2024-08-16 11:41:20 -07:00
Justin Lacy e839618995
Merge branch 'main' of https://github.com/hacksider/Deep-Live-Cam 2024-08-16 08:45:36 -07:00
Justin Lacy a01377c98c
feat: allow drag and drop source files. 2024-08-16 08:45:25 -07:00
3 changed files with 43 additions and 6 deletions

View File

@ -176,6 +176,15 @@ Looking for a CLI mode? Using the -s/--source argument will make the run program
## Want the Next Update Now? ## Want the Next Update Now?
If you want the latest and greatest build, or want to see some new great features, go to our [experimental branch](https://github.com/hacksider/Deep-Live-Cam/tree/experimental) and experience what the contributors have given. If you want the latest and greatest build, or want to see some new great features, go to our [experimental branch](https://github.com/hacksider/Deep-Live-Cam/tree/experimental) and experience what the contributors have given.
## TODO
- [ ] Support multiple faces feature
- [ ] Develop a version for web app/service
- [ ] UI/UX enhancements for desktop app
- [ ] Speed up model loading
- [ ] Speed up real-time face swapping
*Note: This is an open-source project, and were working on it in our free time. Therefore, features, replies, bug fixes, etc., might be delayed. We hope you understand. Thanks.*
## Credits ## Credits
- [ffmpeg](https://ffmpeg.org/): for making video related operations easy - [ffmpeg](https://ffmpeg.org/): for making video related operations easy

View File

@ -1,6 +1,8 @@
import os import os
import webbrowser import webbrowser
import customtkinter as ctk import customtkinter as ctk
from tkinterdnd2 import *
from tkinterdnd2 import TkinterDnD, DND_FILES, DND_ALL
from typing import Callable, Tuple from typing import Callable, Tuple
import cv2 import cv2
from PIL import Image, ImageOps from PIL import Image, ImageOps
@ -34,8 +36,12 @@ status_label = None
img_ft, vid_ft = modules.globals.file_types img_ft, vid_ft = modules.globals.file_types
class CTk(ctk.CTk, TkinterDnD.DnDWrapper):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.TkdndVersion = TkinterDnD._require(self)
def init(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.CTk: def init(start: Callable[[], None], destroy: Callable[[], None]) -> CTk:
global ROOT, PREVIEW global ROOT, PREVIEW
ROOT = create_root(start, destroy) ROOT = create_root(start, destroy)
@ -44,29 +50,38 @@ def init(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.CTk:
return ROOT return ROOT
def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.CTk: def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> CTk:
global source_label, target_label, status_label global source_label, target_label, status_label
ctk.deactivate_automatic_dpi_awareness() ctk.deactivate_automatic_dpi_awareness()
ctk.set_appearance_mode('system') ctk.set_appearance_mode('system')
ctk.set_default_color_theme(resolve_relative_path('ui.json')) ctk.set_default_color_theme(resolve_relative_path('ui.json'))
root = ctk.CTk() root = CTk()
root.minsize(ROOT_WIDTH, ROOT_HEIGHT) root.minsize(ROOT_WIDTH, ROOT_HEIGHT)
root.title(f'{modules.metadata.name} {modules.metadata.version} {modules.metadata.edition}') root.title(f'{modules.metadata.name} {modules.metadata.version} {modules.metadata.edition}')
root.configure() root.configure()
root.protocol('WM_DELETE_WINDOW', lambda: destroy()) root.protocol('WM_DELETE_WINDOW', lambda: destroy())
source_label = ctk.CTkLabel(root, text=None) source_label = ctk.CTkLabel(root, text=None)
source_label.drop_target_register(DND_FILES)
source_label.dnd_bind("<<Drop>>", drop_source_file )
source_label.place(relx=0.1, rely=0.1, relwidth=0.3, relheight=0.25) source_label.place(relx=0.1, rely=0.1, relwidth=0.3, relheight=0.25)
target_label = ctk.CTkLabel(root, text=None) target_label = ctk.CTkLabel(root, text=None)
target_label.drop_target_register(DND_FILES)
target_label.dnd_bind("<<Drop>>", drop_target_file )
target_label.place(relx=0.6, rely=0.1, relwidth=0.3, relheight=0.25) target_label.place(relx=0.6, rely=0.1, relwidth=0.3, relheight=0.25)
select_face_button = ctk.CTkButton(root, text='Select a face', cursor='hand2', command=lambda: select_source_path()) select_face_button = ctk.CTkButton(root, text='Select a face', cursor='hand2', command=lambda: select_source_path())
select_face_button.drop_target_register(DND_FILES)
select_face_button.dnd_bind("<<Drop>>", drop_source_file )
select_face_button.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1) select_face_button.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1)
select_target_button = ctk.CTkButton(root, text='Select a target', cursor='hand2', command=lambda: select_target_path()) select_target_button = ctk.CTkButton(root, text='Select a target', cursor='hand2', command=lambda: select_target_path())
select_target_button.drop_target_register(DND_FILES)
select_target_button.dnd_bind("<<Drop>>", drop_target_file )
select_target_button.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1) select_target_button.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1)
keep_fps_value = ctk.BooleanVar(value=modules.globals.keep_fps) keep_fps_value = ctk.BooleanVar(value=modules.globals.keep_fps)
@ -116,7 +131,6 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
return root return root
def create_preview(parent: ctk.CTkToplevel) -> ctk.CTkToplevel: def create_preview(parent: ctk.CTkToplevel) -> ctk.CTkToplevel:
global preview_label, preview_slider global preview_label, preview_slider
@ -143,12 +157,21 @@ def update_status(text: str) -> None:
def update_tumbler(var: str, value: bool) -> None: def update_tumbler(var: str, value: bool) -> None:
modules.globals.fp_ui[var] = value modules.globals.fp_ui[var] = value
def drop_source_file(e) -> None:
set_source_path( e.data.strip('{}'))
def drop_target_file(e) -> None:
set_target_path( e.data.strip('{}'))
def select_source_path() -> None: def select_source_path() -> None:
global RECENT_DIRECTORY_SOURCE, img_ft, vid_ft global RECENT_DIRECTORY_SOURCE, img_ft, vid_ft
PREVIEW.withdraw() PREVIEW.withdraw()
source_path = ctk.filedialog.askopenfilename(title='select an source image', initialdir=RECENT_DIRECTORY_SOURCE, filetypes=[img_ft]) source_path = ctk.filedialog.askopenfilename(title='select an source image', initialdir=RECENT_DIRECTORY_SOURCE, filetypes=[img_ft])
set_source_path(source_path)
def set_source_path(source_path: str) -> None:
PREVIEW.withdraw()
if is_image(source_path): if is_image(source_path):
modules.globals.source_path = source_path modules.globals.source_path = source_path
RECENT_DIRECTORY_SOURCE = os.path.dirname(modules.globals.source_path) RECENT_DIRECTORY_SOURCE = os.path.dirname(modules.globals.source_path)
@ -158,12 +181,16 @@ def select_source_path() -> None:
modules.globals.source_path = None modules.globals.source_path = None
source_label.configure(image=None) source_label.configure(image=None)
def select_target_path() -> None: def select_target_path() -> None:
global RECENT_DIRECTORY_TARGET, img_ft, vid_ft global RECENT_DIRECTORY_TARGET, img_ft, vid_ft
PREVIEW.withdraw() PREVIEW.withdraw()
target_path = ctk.filedialog.askopenfilename(title='select an target image or video', initialdir=RECENT_DIRECTORY_TARGET, filetypes=[img_ft, vid_ft]) target_path = ctk.filedialog.askopenfilename(title='select an target image or video', initialdir=RECENT_DIRECTORY_TARGET, filetypes=[img_ft, vid_ft])
set_target_path(target_path)
def set_target_path( target_path: str) -> None:
PREVIEW.withdraw()
if is_image(target_path): if is_image(target_path):
modules.globals.target_path = target_path modules.globals.target_path = target_path
RECENT_DIRECTORY_TARGET = os.path.dirname(modules.globals.target_path) RECENT_DIRECTORY_TARGET = os.path.dirname(modules.globals.target_path)

View File

@ -6,6 +6,7 @@ onnx==1.16.0
insightface==0.7.3 insightface==0.7.3
psutil==5.9.8 psutil==5.9.8
tk==0.1.0 tk==0.1.0
tkinterdnd2==0.4.2
customtkinter==5.2.2 customtkinter==5.2.2
pillow==9.5.0 pillow==9.5.0
torch==2.0.1+cu118; sys_platform != 'darwin' torch==2.0.1+cu118; sys_platform != 'darwin'