diff --git a/iz_helpers/InfZoomConfig.py b/iz_helpers/InfZoomConfig.py
new file mode 100644
index 0000000..9cdfa78
--- /dev/null
+++ b/iz_helpers/InfZoomConfig.py
@@ -0,0 +1,36 @@
+from dataclasses import dataclass
+from PIL import Image
+@dataclass
+class InfZoomConfig():
+ common_prompt_pre:str
+ prompts_array:list[str]
+ common_prompt_suf:str
+ negative_prompt:str
+ num_outpainting_steps: int
+ guidance_scale:float
+ num_inference_steps:int
+ custom_init_image:Image
+ custom_exit_image:Image
+ video_frame_rate:int
+ video_zoom_mode:int #0: ZoomOut, 1: ZoomIn
+ video_start_frame_dupe_amount:int
+ video_last_frame_dupe_amount:int
+ video_ffmpeg_opts: str
+ inpainting_mask_blur:int
+ inpainting_fill_mode:int
+ zoom_speed:float
+ seed:int
+ outputsizeW:int
+ outputsizeH:int
+ batchcount:int
+ sampler:str
+ upscale_do:bool
+ upscaler_name:str
+ upscale_by:float
+ overmask:int
+ outpaintStrategy: str
+ inpainting_denoising_strength:float=1
+ inpainting_full_res:int =0
+ inpainting_padding:int=0
+ outpaint_amount_px: int=64
+ progress:any=None
diff --git a/iz_helpers/image.py b/iz_helpers/image.py
index 8876c02..a2adc58 100644
--- a/iz_helpers/image.py
+++ b/iz_helpers/image.py
@@ -42,6 +42,8 @@ def open_image(image_path):
Returns:
Image: A PIL Image object of the opened image.
"""
+ # Strip leading and trailing double quotation marks, if present
+ image_path = image_path.strip('"')
if image_path.startswith('http'):
# If the image path is a URL, download the image using requests
response = requests.get(image_path)
diff --git a/iz_helpers/run.py b/iz_helpers/run.py
index 9246da9..d5b2d8a 100644
--- a/iz_helpers/run.py
+++ b/iz_helpers/run.py
@@ -1,5 +1,8 @@
import math, time, os
import numpy as np
+from scipy.signal import savgol_filter
+from typing import Callable
+import cv2
from PIL import Image, ImageFilter, ImageDraw, ImageColor
from modules.ui import plaintext_to_html
import modules.shared as shared
@@ -13,7 +16,15 @@ from .helpers import (
)
from .sd_helpers import renderImg2Img, renderTxt2Img
from .image import shrink_and_paste_on_blank, open_image, apply_alpha_mask, draw_gradient_ellipse, resize_and_crop_image, crop_fethear_ellipse, crop_inner_image
-from .video import write_video, add_audio_to_video
+from .video import write_video, add_audio_to_video, ContinuousVideoWriter
+from .InfZoomConfig import InfZoomConfig
+
+class InfZoomer:
+ def __init__(self, config: InfZoomConfig) -> None:
+ self.C = config
+ self.prompts = {}
+ self.main_frames = []
+ self.out_config = {}
def outpaint_steps(
width,
@@ -193,6 +204,7 @@ def create_zoom(
video_zoom_mode,
video_start_frame_dupe_amount,
video_last_frame_dupe_amount,
+ video_ffmpeg_opts,
inpainting_mask_blur,
inpainting_fill_mode,
zoom_speed,
@@ -204,6 +216,9 @@ def create_zoom(
upscale_do,
upscaler_name,
upscale_by,
+ overmask,
+ outpaintStrategy,
+ outpaint_amount_px,
blend_image,
blend_mode,
blend_gradient_size,
diff --git a/iz_helpers/run_interface.py b/iz_helpers/run_interface.py
new file mode 100644
index 0000000..9403128
--- /dev/null
+++ b/iz_helpers/run_interface.py
@@ -0,0 +1,77 @@
+from .run import (InfZoomer)
+from .InfZoomConfig import InfZoomConfig
+from PIL import Image
+
+# to be called from Gradio or other client
+def createZoom(
+ common_prompt_pre:str,
+ prompts_array:list[str],
+ common_prompt_suf:str,
+ negative_prompt:str,
+ num_outpainting_steps: int,
+ guidance_scale:float,
+ num_inference_steps:int,
+ custom_init_image:Image,
+ custom_exit_image:Image,
+ video_frame_rate:int,
+ video_zoom_mode:int,
+ video_start_frame_dupe_amount:int,
+ video_last_frame_dupe_amount:int,
+ video_ffmpeg_opts:str,
+ inpainting_mask_blur:int,
+ inpainting_fill_mode:int,
+ zoom_speed:float,
+ seed:int,
+ outputsizeW:int,
+ outputsizeH:int,
+ batchcount:int,
+ sampler:str,
+ upscale_do:bool,
+ upscaler_name:str,
+ upscale_by:float,
+ overmask:int,
+ outpaintStrategy:str,
+ outpaint_amount_px: int,
+ inpainting_denoising_strength:float=1,
+ inpainting_full_res:int =0,
+ inpainting_padding:int=0,
+ progress:any=None
+):
+ izc = InfZoomConfig(
+ common_prompt_pre,
+ prompts_array,
+ common_prompt_suf,
+ negative_prompt,
+ num_outpainting_steps,
+ guidance_scale,
+ num_inference_steps,
+ custom_init_image,
+ custom_exit_image,
+ video_frame_rate,
+ video_zoom_mode,
+ video_start_frame_dupe_amount,
+ video_last_frame_dupe_amount,
+ video_ffmpeg_opts,
+ inpainting_mask_blur,
+ inpainting_fill_mode,
+ zoom_speed,
+ seed,
+ outputsizeW,
+ outputsizeH,
+ batchcount,
+ sampler,
+ upscale_do,
+ upscaler_name,
+ upscale_by,
+ overmask,
+ outpaintStrategy,
+ inpainting_denoising_strength,
+ inpainting_full_res,
+ inpainting_padding,
+ outpaint_amount_px,
+ progress
+ )
+ iz= InfZoomer(izc)
+ r = iz.create_zoom()
+ del iz
+ return r
diff --git a/iz_helpers/ui.py b/iz_helpers/ui.py
index 751a7a4..e014abe 100644
--- a/iz_helpers/ui.py
+++ b/iz_helpers/ui.py
@@ -5,6 +5,7 @@ from .run import create_zoom
import modules.shared as shared
from webui import wrap_gradio_gpu_call
from modules.ui import create_output_panel
+from .run_interface import createZoom
from .static_variables import (
default_prompt,
@@ -16,6 +17,7 @@ from .static_variables import (
default_cfg_scale,
default_mask_blur,
default_sampler,
+ default_overmask,
default_gradient_size,
)
from .helpers import validatePromptJson_throws, putPrompts, clearPrompts, renumberDataframe
@@ -175,6 +177,23 @@ def on_ui_tabs():
step=0.1,
info="Zoom speed in seconds (higher values create slower zoom)",
)
+ with gr.Accordion("FFMPEG Expert", open=False):
+ gr.Markdown(
+ """# I need FFMPEG control
+You can put CLI options here as documented FFMPEG OPTIONS and FILTER OPTIONS
+
+## Examples:
+* ```-vf crop=200:200``` crop down to 200x200 pixel from center (useful to cutoff jumpy borders)
+* ```-vf scale=320:240``` scales your video to 320x240
+* ```-c:v libx264 -preset veryslow -qp 0``` uses lossless compression
+
+You might give multiple options in one line.
+
+"""
+)
+ video_ffmpeg_opts=gr.Textbox(
+ value="", label="FFMPEG Opts"
+ )
with gr.Accordion("Blend settings"):
with gr.Row():
blend_image = gr.Image(type="pil", label="Custom in/out Blend Image")
@@ -223,12 +242,27 @@ Ideas for custom blend images: https://www.pexels.com/search/gradient/
audio_file.change(get_filename, inputs=[audio_file], outputs=[audio_filename])
with gr.Tab("Outpaint"):
+ outpaint_amount_px = gr.Slider(
+ label="Outpaint pixels",
+ minimum=4,
+ maximum=508,
+ step=8,
+ value=64,
+ )
+
inpainting_mask_blur = gr.Slider(
label="Mask Blur",
minimum=0,
maximum=64,
+ step=1,
value=default_mask_blur,
- step=1
+ )
+ overmask = gr.Slider(
+ label="Overmask (px) paint a bit into centered image",
+ minimum=0,
+ maximum=64,
+ step=1,
+ value=default_overmask,
)
inpainting_fill_mode = gr.Radio(
label="Masked content",
@@ -237,6 +271,15 @@ Ideas for custom blend images: https://www.pexels.com/search/gradient/
type="index",
)
+ outpaintStrategy= gr.Radio(
+ label="Outpaint Strategy",
+ choices=["Center", "Corners"],
+ value="Corners",
+ type="value"
+ )
+
+
+
with gr.Tab("Post proccess"):
upscale_do = gr.Checkbox(False, label="Enable Upscale")
upscaler_name = gr.Dropdown(
@@ -358,6 +401,7 @@ Our best experience and trade-off is the R-ERSGAn4x upscaler.
video_zoom_mode,
video_start_frame_dupe_amount,
video_last_frame_dupe_amount,
+ video_ffmpeg_opts,
inpainting_mask_blur,
inpainting_fill_mode,
video_zoom_speed,
@@ -369,6 +413,9 @@ Our best experience and trade-off is the R-ERSGAn4x upscaler.
upscale_do,
upscaler_name,
upscale_by,
+ overmask,
+ outpaintStrategy,
+ outpaint_amount_px,
blend_image,
blend_mode,
blend_gradient_size,
diff --git a/iz_helpers/video.py b/iz_helpers/video.py
index 9f06ca9..af5f715 100644
--- a/iz_helpers/video.py
+++ b/iz_helpers/video.py
@@ -70,41 +70,44 @@ def write_video(file_path, frames, fps, reversed=True, start_frame_dupe_amount=1
writer.close()
- class ContinuousVideoWriter:
+class ContinuousVideoWriter:
- _writer = None
+ _writer = None
- def __init__(self, file_path, initframe, fps, start_frame_dupe_amount=15):
- """
- Writes initial frame to a new mp4 video file
- :param file_path: Path to output video, must end with .mp4
- :param frame: Start image PIL.Image objects
- :param fps: Desired frame rate
- :param reversed: if order of images to be reversed (default = True)
- """
+ def __init__(self, file_path, initframe, fps, start_frame_dupe_amount=15, video_ffmpeg_opts="" ):
+ """
+ Writes initial frame to a new mp4 video file
+ :param file_path: Path to output video, must end with .mp4
+ :param frame: Start image PIL.Image objects
+ :param fps: Desired frame rate
+ :param reversed: if order of images to be reversed (default = True)
+ """
+ ffopts = []
+ if video_ffmpeg_opts is not "":
+ ffopts= video_ffmpeg_opts.split(" ")
- writer = imageio.get_writer(file_path, fps=fps, macro_block_size=None)
- start_frames = [initframe] * start_frame_dupe_amount
- for f in start_frames:
- writer.append_data(np.array(f))
- self._writer = writer
+ writer = imageio.get_writer(file_path, fps=fps, macro_block_size=None, ffmpeg_params=ffopts)
+ start_frames = [initframe] * start_frame_dupe_amount
+ for f in start_frames:
+ writer.append_data(np.array(f))
+ self._writer = writer
- def append(self, frames):
- """
- Append a list of image PIL.Image objects to the end of the file.
- :param frames: List of image PIL.Image objects
- """
- for i,f in enumerate(frames):
- self._writer.append_data(np.array(f))
+ def append(self, frames):
+ """
+ Append a list of image PIL.Image objects to the end of the file.
+ :param frames: List of image PIL.Image objects
+ """
+ for i,f in enumerate(frames):
+ self._writer.append_data(np.array(f))
- def finish(self, frame, last_frame_dupe_amount=30 ):
- """
- Closes the file writer.
- """
- for i in range(last_frame_dupe_amount):
- self._writer.append_data(np.array(frame))
+ def finish(self, frame, last_frame_dupe_amount=30 ):
+ """
+ Closes the file writer.
+ """
+ for i in range(last_frame_dupe_amount):
+ self._writer.append_data(np.array(frame))
- self._writer.close()
+ self._writer.close()
def add_audio_to_video(video_path, audio_path, output_path, ffmpeg_location = 'ffmpeg'):
command = [ffmpeg_location, '-i', video_path, '-i', audio_path, '-c:v', 'copy', '-c:a', 'aac', '-map', '0:v:0', '-map', '1:a:0', '-shortest', output_path]