parent
961ac85cde
commit
cc3a50ea0e
|
|
@ -34,6 +34,7 @@ class InfZoomConfig():
|
|||
blend_gradient_size:int
|
||||
blend_invert_do:bool
|
||||
blend_color:str
|
||||
lut_filename:str=None
|
||||
audio_filename:str=None
|
||||
audio_volume:float = 1
|
||||
inpainting_denoising_strength:float=1
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@ import base64
|
|||
import numpy as np
|
||||
import math
|
||||
from io import BytesIO
|
||||
import os
|
||||
from modules.processing import apply_overlay, slerp
|
||||
from timeit import default_timer as timer
|
||||
from typing import List, Union
|
||||
|
||||
|
||||
def shrink_and_paste_on_blank(current_image, mask_width, mask_height, blank_color:tuple[int, int, int, int] = (0,0,0,0)):
|
||||
|
|
@ -91,6 +93,8 @@ def convert_to_rgba(images):
|
|||
print(f"rgb convert:{end - start}")
|
||||
return rgba_images
|
||||
|
||||
######################################################## lerp ########################################################
|
||||
|
||||
def lerp(value1, value2, factor):
|
||||
"""
|
||||
Linearly interpolate between value1 and value2 by factor.
|
||||
|
|
@ -195,6 +199,77 @@ def lerp_imagemath_RGBA(img1, img2, alphaimg, factor:int = 50):
|
|||
def CMYKInvert(img) :
|
||||
return Image.merge(img.mode, [ImageOps.invert(b.convert('L')) for b in img.split()])
|
||||
|
||||
##################################################### LUTs ############################################################
|
||||
|
||||
def is_3dlut_row(row: List[str]) -> bool:
|
||||
"""
|
||||
Check if one line in the file has exactly 3 numeric values.
|
||||
|
||||
Args:
|
||||
row: A list of strings representing the values in a row.
|
||||
|
||||
Returns:
|
||||
True if the row has exactly 3 numeric values, False otherwise.
|
||||
"""
|
||||
try:
|
||||
row_values = [float(val) for val in row]
|
||||
return len(row_values) == 3
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
|
||||
def read_lut(path_lut: Union[str, os.PathLike], num_channels: int = 3) -> ImageFilter.Color3DLUT:
|
||||
"""
|
||||
Read LUT from a raw file.
|
||||
|
||||
Each line in the file is considered part of the LUT table. The function
|
||||
reads the file, parses the rows, and constructs a Color3DLUT object.
|
||||
|
||||
Args:
|
||||
path_lut: A string or os.PathLike object representing the path to the LUT file.
|
||||
num_channels: An integer specifying the number of color channels in the LUT (default is 3).
|
||||
|
||||
Returns:
|
||||
An instance of ImageFilter.Color3DLUT representing the LUT.
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: If the LUT file specified by path_lut does not exist.
|
||||
"""
|
||||
with open(path_lut) as f:
|
||||
lut_raw = f.read().splitlines()
|
||||
|
||||
size = round(len(lut_raw) ** (1 / 3))
|
||||
row2val = lambda row: tuple([float(val) for val in row.split(" ")])
|
||||
lut_table = [row2val(row) for row in lut_raw if is_3dlut_row(row.split(" "))]
|
||||
|
||||
return ImageFilter.Color3DLUT(size, lut_table, num_channels)
|
||||
|
||||
def apply_lut(img: Image, lut_path: str = "", lut: ImageFilter.Color3DLUT = None) -> Image:
|
||||
"""
|
||||
Apply a LUT to an image and return a PIL Image with the LUT applied.
|
||||
|
||||
The function applies the LUT to the input image using the filter() method of the PIL Image class.
|
||||
|
||||
Args:
|
||||
img: A PIL Image object to which the LUT should be applied.
|
||||
lut_path: A string representing the path to the LUT file (optional if lut argument is provided).
|
||||
lut: An instance of ImageFilter.Color3DLUT representing the LUT (optional if lut_path is provided).
|
||||
|
||||
Returns:
|
||||
A PIL Image object with the LUT applied.
|
||||
|
||||
Raises:
|
||||
ValueError: If both lut_path and lut arguments are not provided.
|
||||
"""
|
||||
if lut is None:
|
||||
if lut_path == "":
|
||||
raise ValueError("Either lut_path or lut argument must be provided.")
|
||||
lut = read_lut(lut_path)
|
||||
|
||||
return img.filter(lut)
|
||||
|
||||
##################################################### Masks ############################################################
|
||||
|
||||
def combine_masks(mask:Image, altmask:Image, width:int, height:int):
|
||||
"""
|
||||
Combine two masks using lighter color
|
||||
|
|
@ -208,6 +283,8 @@ def combine_masks(mask:Image, altmask:Image, width:int, height:int):
|
|||
result = ImageChops.lighter(mask, altmask)
|
||||
return result
|
||||
|
||||
##################################################### Gradients #########################################################
|
||||
|
||||
def clip_gradient_image(gradient_image, min_value:int = 50, max_value:int =75, invert= False, mask = False):
|
||||
"""
|
||||
Return only the values of a gradient grayscale image between a minimum and maximum value.
|
||||
|
|
@ -668,6 +745,8 @@ def multiply_alpha(image, factor):
|
|||
print(f"multiply_alpha:{end - start}")
|
||||
return result_image
|
||||
|
||||
#################################################################### Blends and Wipes ####################################################################
|
||||
|
||||
def blend_images(start_image: Image, stop_image: Image, num_frames: int, invert:bool = False) -> list:
|
||||
"""
|
||||
Blend two images together via the alpha amount of each frame.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,17 @@ from .helpers import (
|
|||
do_upscaleImg,value_to_bool, find_ffmpeg_binary
|
||||
)
|
||||
from .sd_helpers import renderImg2Img, renderTxt2Img
|
||||
from .image import multiply_alpha, shrink_and_paste_on_blank, open_image, apply_alpha_mask, draw_gradient_ellipse, resize_and_crop_image, crop_fethear_ellipse, crop_inner_image, combine_masks
|
||||
from .image import (
|
||||
multiply_alpha,
|
||||
shrink_and_paste_on_blank,
|
||||
open_image,
|
||||
apply_alpha_mask,
|
||||
draw_gradient_ellipse,
|
||||
resize_and_crop_image,
|
||||
crop_fethear_ellipse,
|
||||
crop_inner_image,
|
||||
apply_lut,
|
||||
read_lut)
|
||||
from .video import write_video, add_audio_to_video, ContinuousVideoWriter
|
||||
from .InfZoomConfig import InfZoomConfig
|
||||
|
||||
|
|
@ -117,6 +127,13 @@ class InfZoomer:
|
|||
|
||||
processed = self.fnOutpaintMainFrames()
|
||||
|
||||
if self.C.lut_filename is not None:
|
||||
try:
|
||||
#processed = apply_lut(processed, self.C.lut_filename)
|
||||
self.main_frames = [apply_lut(frame, self.C.lut_filename) for frame in self.main_frames]
|
||||
except Exception as e:
|
||||
input(f"Skip LUT: Error applying LUT {str(e)}. Enter to continue...")
|
||||
|
||||
#trim frames that are blended or luma wiped
|
||||
self.start_frames = self.main_frames[:2]
|
||||
self.end_frames = self.main_frames[(len(self.main_frames) - 2):]
|
||||
|
|
@ -231,6 +248,7 @@ class InfZoomer:
|
|||
|
||||
def outpaint_steps_cornerStrategy(self):
|
||||
current_image = self.main_frames[-1]
|
||||
exit_img = None
|
||||
|
||||
# just 30 radius to get inpaint connected between outer and innter motive
|
||||
masked_image = create_mask_with_circles(
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ def createZoom(
|
|||
blend_gradient_size:int,
|
||||
blend_invert_do:bool,
|
||||
blend_color:str,
|
||||
lut_filename:str=None,
|
||||
audio_filename:str = None,
|
||||
audio_volume:float = 1,
|
||||
inpainting_denoising_strength:float=1,
|
||||
|
|
@ -77,6 +78,7 @@ def createZoom(
|
|||
blend_gradient_size,
|
||||
blend_invert_do,
|
||||
blend_color,
|
||||
lut_filename,
|
||||
audio_filename,
|
||||
audio_volume,
|
||||
inpainting_denoising_strength,
|
||||
|
|
|
|||
|
|
@ -241,6 +241,18 @@ Free to use grayscale blend images can be found here: https://github.com/Oncorpo
|
|||
Ideas for custom blend images: https://www.pexels.com/search/gradient/
|
||||
"""
|
||||
)
|
||||
with gr.Row():
|
||||
lut_filename = gr.Textbox(
|
||||
value=None,
|
||||
label="Look Up Table (LUT) File Name",
|
||||
elem_id="infzoom_lutFileName")
|
||||
lut_file = gr.File(
|
||||
value=None,
|
||||
file_count="single",
|
||||
file_types=[".cube"],
|
||||
type="file",
|
||||
label="LUT cube File")
|
||||
lut_file.change(get_filename, inputs=[lut_file], outputs=[lut_filename])
|
||||
|
||||
with gr.Tab("Audio"):
|
||||
with gr.Row():
|
||||
|
|
@ -447,6 +459,7 @@ Our best experience and trade-off is the R-ERSGAn4x upscaler.
|
|||
blend_gradient_size,
|
||||
blend_invert_do,
|
||||
blend_color,
|
||||
lut_filename,
|
||||
audio_filename,
|
||||
audio_volume,
|
||||
],
|
||||
|
|
@ -469,7 +482,10 @@ def checkPrompts(p):
|
|||
)
|
||||
|
||||
def get_filename(file):
|
||||
return file.name
|
||||
filename = None
|
||||
if file is not None:
|
||||
filename = file.name
|
||||
return filename
|
||||
|
||||
def get_min_outpaint_amount(width, outpaint_amount, strategy):
|
||||
#automatically sets the minimum outpaint amount based on the width for Center strategy
|
||||
|
|
|
|||
Loading…
Reference in New Issue