diff --git a/iz_helpers/run.py b/iz_helpers/run.py index 811fe58..b7c83dd 100644 --- a/iz_helpers/run.py +++ b/iz_helpers/run.py @@ -12,7 +12,7 @@ from .helpers import ( ) from .sd_helpers import renderImg2Img, renderTxt2Img from .image import shrink_and_paste_on_blank -from .video import write_video +from .video import ContinuousVideoWriter def crop_fethear_ellipse(image, feather_margin=30, width_offset=0, height_offset=0): # Create a blank mask image with the same size as the original image @@ -382,11 +382,6 @@ def create_zoom_single( num_interpol_frames = round(video_frame_rate * zoom_speed) - all_frames = [] - - if upscale_do and progress: - progress(0, desc="upscaling inital image") - load_model_from_setting( "infzoom_inpainting_model", progress, "Loading Model for inpainting/img2img: " ) @@ -416,27 +411,24 @@ def create_zoom_single( ) if (upscale_do): - for mf,idx in main_frames: + for idx,mf in enumerate(main_frames): + print (f"InfZoom: Upscaling mainframe: {idx} \r") main_frames[idx]=do_upscaleImg(mf, upscale_do, upscaler_name, upscale_by) + width = main_frames[0].width height = main_frames[0].height mask_width = width/4 mask_height = height/4 - all_frames.append(main_frames[0]) + if video_zoom_mode: + main_frames = main_frames[::-1] + + contVW = ContinuousVideoWriter(out_config["video_filename"], main_frames[0],video_frame_rate,int(video_start_frame_dupe_amount)) - interpolateFrames(num_outpainting_steps, progress, out_config, width, height, mask_width, mask_height, num_interpol_frames, all_frames, main_frames) + interpolateFrames(out_config, width, height, mask_width, mask_height, num_interpol_frames, contVW, main_frames, video_zoom_mode) - frames2Collect(all_frames, out_config) + contVW.finish(main_frames[-1],int(video_last_frame_dupe_amount)) - write_video( - out_config["video_filename"], - all_frames, - video_frame_rate, - video_zoom_mode, - int(video_start_frame_dupe_amount), - int(video_last_frame_dupe_amount), - ) print("Video saved in: " + os.path.join(script_path, out_config["video_filename"])) return ( @@ -447,11 +439,18 @@ def create_zoom_single( plaintext_to_html(""), ) -def interpolateFrames(num_outpainting_steps, progress, out_config, width, height, mask_width, mask_height, num_interpol_frames, all_frames, main_frames): +def interpolateFrames(out_config, width, height, mask_width, mask_height, num_interpol_frames, contVW, main_frames, zoomIn): for i in range(len(main_frames) - 1): # interpolation steps between 2 inpainted images (=sequential zoom and crop) for j in range(num_interpol_frames - 1): - current_image = main_frames[i + 1] + + print (f"InfZoom: Interpolate frame: main/inter: {i}/{j} \r") + #todo: howto zoomIn when writing each frame; main_frames are inverted, howto interpolate? + if zoomIn: + current_image = main_frames[i + 1] + else: + current_image = main_frames[i + 1] + interpol_image = current_image save2Collect(interpol_image, out_config, f"interpol_img_{i}_{j}].png") @@ -507,6 +506,6 @@ def interpolateFrames(num_outpainting_steps, progress, out_config, width, height interpol_image.paste(prev_image_fix_crop, mask=prev_image_fix_crop) save2Collect(interpol_image, out_config, f"interpol_prevcrop_{i}_{j}.png") - all_frames.append(interpol_image) + contVW.append([interpol_image]) - all_frames.append(current_image) + contVW.append([current_image]) diff --git a/iz_helpers/ui.py b/iz_helpers/ui.py index 2c33446..92d2dbe 100644 --- a/iz_helpers/ui.py +++ b/iz_helpers/ui.py @@ -183,6 +183,7 @@ def on_ui_tabs(): value=30, minimum=1, maximum=60, + step=1 ) video_zoom_mode = gr.Radio( label="Zoom mode", @@ -196,6 +197,7 @@ def on_ui_tabs(): value=0, minimum=1, maximum=60, + step=1 ) video_last_frame_dupe_amount = gr.Slider( label="number of last frame dupe", @@ -203,6 +205,7 @@ def on_ui_tabs(): value=0, minimum=1, maximum=60, + step=1 ) video_zoom_speed = gr.Slider( label="Zoom Speed", @@ -218,12 +221,14 @@ def on_ui_tabs(): label="Mask Blur", minimum=0, maximum=64, + step=1, value=default_mask_blur, ) 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( diff --git a/iz_helpers/video.py b/iz_helpers/video.py index cb1c5d9..c665eff 100644 --- a/iz_helpers/video.py +++ b/iz_helpers/video.py @@ -35,9 +35,47 @@ def write_video(file_path, frames, fps, reversed=True, start_frame_dupe_amount=1 writer.append_data(np_frame) # Write the duplicated frames to the video writer - for frame in end_frames: + for frame in end_frames: np_frame = np.array(frame) writer.append_data(np_frame) # Close the video writer - writer.close() \ No newline at end of file + writer.close() + + +class ContinuousVideoWriter: + + _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) + """ + + 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 + + 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)) + + self._writer.close() + \ No newline at end of file