Sticky preview only for landscape images and videos

This commit is contained in:
henryruhs 2024-09-17 19:51:33 +02:00
parent 74030f725b
commit 7c6a7ce509
4 changed files with 23 additions and 5 deletions

View File

@ -68,6 +68,7 @@ MelFilterBank = NDArray[Any]
Fps = float Fps = float
Padding = Tuple[int, int, int, int] Padding = Tuple[int, int, int, int]
Orientation = Literal['landscape', 'portrait']
Resolution = Tuple[int, int] Resolution = Tuple[int, int]
ProcessState = Literal['checking', 'processing', 'stopping', 'pending'] ProcessState = Literal['checking', 'processing', 'stopping', 'pending']

View File

@ -87,3 +87,10 @@
{ {
object-fit: cover; object-fit: cover;
} }
:root:root:root:root .image-preview.is-landscape
{
position: sticky;
top: 0;
z-index: 100;
}

View File

@ -17,7 +17,7 @@ from facefusion.processors.core import get_processors_modules
from facefusion.typing import AudioFrame, Face, FaceSet, VisionFrame from facefusion.typing import AudioFrame, Face, FaceSet, VisionFrame
from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component
from facefusion.uis.typing import ComponentOptions from facefusion.uis.typing import ComponentOptions
from facefusion.vision import count_video_frame_total, get_video_frame, normalize_frame_color, read_static_image, read_static_images, resize_frame_resolution from facefusion.vision import count_video_frame_total, detect_frame_orientation, get_video_frame, normalize_frame_color, read_static_image, read_static_images, resize_frame_resolution
PREVIEW_IMAGE : Optional[gradio.Image] = None PREVIEW_IMAGE : Optional[gradio.Image] = None
PREVIEW_FRAME_SLIDER : Optional[gradio.Slider] = None PREVIEW_FRAME_SLIDER : Optional[gradio.Slider] = None
@ -56,11 +56,13 @@ def render() -> None:
target_vision_frame = read_static_image(state_manager.get_item('target_path')) target_vision_frame = read_static_image(state_manager.get_item('target_path'))
preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, target_vision_frame) preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, target_vision_frame)
preview_image_options['value'] = normalize_frame_color(preview_vision_frame) preview_image_options['value'] = normalize_frame_color(preview_vision_frame)
preview_image_options['elem_classes'] = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ]
if is_video(state_manager.get_item('target_path')): if is_video(state_manager.get_item('target_path')):
temp_vision_frame = get_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number')) temp_vision_frame = get_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, temp_vision_frame) preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, temp_vision_frame)
preview_image_options['value'] = normalize_frame_color(preview_vision_frame) preview_image_options['value'] = normalize_frame_color(preview_vision_frame)
preview_image_options['elem_classes'] = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ]
preview_image_options['visible'] = True preview_image_options['visible'] = True
preview_frame_slider_options['value'] = state_manager.get_item('reference_frame_number') preview_frame_slider_options['value'] = state_manager.get_item('reference_frame_number')
preview_frame_slider_options['maximum'] = count_video_frame_total(state_manager.get_item('target_path')) preview_frame_slider_options['maximum'] = count_video_frame_total(state_manager.get_item('target_path'))
@ -202,14 +204,14 @@ def update_preview_image(frame_number : int = 0) -> gradio.Image:
target_vision_frame = read_static_image(state_manager.get_item('target_path')) target_vision_frame = read_static_image(state_manager.get_item('target_path'))
preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, target_vision_frame) preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, target_vision_frame)
preview_vision_frame = normalize_frame_color(preview_vision_frame) preview_vision_frame = normalize_frame_color(preview_vision_frame)
return gradio.Image(value = preview_vision_frame) return gradio.Image(value = preview_vision_frame, elem_classes = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ])
if is_video(state_manager.get_item('target_path')): if is_video(state_manager.get_item('target_path')):
temp_vision_frame = get_video_frame(state_manager.get_item('target_path'), frame_number) temp_vision_frame = get_video_frame(state_manager.get_item('target_path'), frame_number)
preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, temp_vision_frame) preview_vision_frame = process_preview_frame(reference_faces, source_face, source_audio_frame, temp_vision_frame)
preview_vision_frame = normalize_frame_color(preview_vision_frame) preview_vision_frame = normalize_frame_color(preview_vision_frame)
return gradio.Image(value = preview_vision_frame) return gradio.Image(value = preview_vision_frame, elem_classes = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ])
return gradio.Image(value = None) return gradio.Image(value = None, elem_classes = None)
def update_preview_frame_slider() -> gradio.Slider: def update_preview_frame_slider() -> gradio.Slider:

View File

@ -8,7 +8,7 @@ from cv2.typing import Size
from facefusion.choices import image_template_sizes, video_template_sizes from facefusion.choices import image_template_sizes, video_template_sizes
from facefusion.common_helper import is_windows from facefusion.common_helper import is_windows
from facefusion.filesystem import is_image, is_video, sanitize_path_for_windows from facefusion.filesystem import is_image, is_video, sanitize_path_for_windows
from facefusion.typing import Fps, Resolution, VisionFrame from facefusion.typing import Fps, Orientation, Resolution, VisionFrame
@lru_cache(maxsize = 128) @lru_cache(maxsize = 128)
@ -178,6 +178,14 @@ def unpack_resolution(resolution : str) -> Resolution:
return width, height return width, height
def detect_frame_orientation(vision_frame : VisionFrame) -> Orientation:
height, width = vision_frame.shape[:2]
if width > height:
return 'landscape'
return 'portrait'
def resize_frame_resolution(vision_frame : VisionFrame, max_resolution : Resolution) -> VisionFrame: def resize_frame_resolution(vision_frame : VisionFrame, max_resolution : Resolution) -> VisionFrame:
height, width = vision_frame.shape[:2] height, width = vision_frame.shape[:2]
max_width, max_height = max_resolution max_width, max_height = max_resolution