LayerFilter: Film¶
Documentation¶
- Class name:
LayerFilter: Film
- Category:
😺dzNodes/LayerFilter
- Output node:
False
The Film node applies a cinematic film effect to images, enhancing them with a specific aesthetic that emulates the look and feel of traditional film photography. This node is designed to transform digital images by applying various film-like attributes, such as color grading, grain, and contrast adjustments, to achieve a visually appealing, filmic quality.
Input types¶
Required¶
image
- The primary input for the Film node, representing the image to which the film effect will be applied. This parameter is crucial as it determines the base upon which all film-like transformations are performed.
- Comfy dtype:
IMAGE
- Python dtype:
torch.Tensor
center_x
- Specifies the horizontal center of the effect focus, influencing how certain effects like blur and vignette are centered on the image.
- Comfy dtype:
FLOAT
- Python dtype:
float
center_y
- Determines the vertical center of the effect focus, affecting the positioning of effects such as blur and vignette on the image.
- Comfy dtype:
FLOAT
- Python dtype:
float
saturation
- Controls the intensity of the image's colors, allowing for either a more vivid or subdued color palette.
- Comfy dtype:
FLOAT
- Python dtype:
float
vignette_intensity
- Adjusts the strength of the vignette effect, adding a darkened border that can focus attention towards the center of the image.
- Comfy dtype:
FLOAT
- Python dtype:
float
grain_power
- Sets the intensity of the film grain effect, adding a textured, analog feel to the image.
- Comfy dtype:
FLOAT
- Python dtype:
float
grain_scale
- Determines the scale of the grain effect, affecting how large or fine the grain particles appear.
- Comfy dtype:
FLOAT
- Python dtype:
float
grain_sat
- Adjusts the saturation of the grain effect, influencing how pronounced the grain appears in color.
- Comfy dtype:
FLOAT
- Python dtype:
float
grain_shadows
- Controls the visibility of grain in the darker areas of the image, allowing for more or less texture in shadows.
- Comfy dtype:
FLOAT
- Python dtype:
float
grain_highs
- Adjusts the grain effect in the highlights, modifying how grain affects brighter areas of the image.
- Comfy dtype:
FLOAT
- Python dtype:
float
blur_strength
- Sets the intensity of the blur effect, which can simulate depth of field or focus effects.
- Comfy dtype:
INT
- Python dtype:
int
blur_focus_spread
- Controls the spread of the blur effect around the focus point, affecting the transition between focused and blurred areas.
- Comfy dtype:
FLOAT
- Python dtype:
float
focal_depth
- Determines the depth of the focal area, influencing how much of the image appears in focus.
- Comfy dtype:
FLOAT
- Python dtype:
float
Optional¶
depth_map
- An optional parameter that provides a depth map for more advanced depth-based effects like variable blur.
- Comfy dtype:
IMAGE
- Python dtype:
torch.Tensor
Output types¶
image
- Comfy dtype:
IMAGE
- The output of the Film node is an image that has been processed to emulate the appearance of film, incorporating adjustments to color, grain, and contrast to enhance its cinematic quality.
- Python dtype:
torch.Tensor
- Comfy dtype:
Usage tips¶
- Infra type:
GPU
- Common nodes: unknown
Source code¶
class Film:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(self):
return {
"required": {
"image": ("IMAGE", ), #
"center_x": ("FLOAT", {"default": 0.5, "min": 0, "max": 1, "step": 0.01}),
"center_y": ("FLOAT", {"default": 0.5, "min": 0, "max": 1, "step": 0.01}),
"saturation": ("FLOAT", {"default": 1, "min": 0.01, "max": 3, "step": 0.01}),
"vignette_intensity": ("FLOAT", {"default": 0.5, "min": 0, "max": 1, "step": 0.01}),
"grain_power": ("FLOAT", {"default": 0.15, "min": 0, "max": 1, "step": 0.01}),
"grain_scale": ("FLOAT", {"default": 1.0, "min": 0.1, "max": 10, "step": 0.1}),
"grain_sat": ("FLOAT", {"default": 0.5, "min": 0, "max": 1, "step": 0.01}),
"grain_shadows": ("FLOAT", {"default": 0.6, "min": 0, "max": 1, "step": 0.01}),
"grain_highs": ("FLOAT", {"default": 0.2, "min": 0, "max": 1, "step": 0.01}),
"blur_strength": ("INT", {"default": 90, "min": 0, "max": 256, "step": 1}),
"blur_focus_spread": ("FLOAT", {"default": 2.2, "min": 0.1, "max": 8, "step": 0.1}),
"focal_depth": ("FLOAT", {"default": 0.9, "min": 0.0, "max": 1, "step": 0.01}),
},
"optional": {
"depth_map": ("IMAGE",), #
}
}
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = 'film'
CATEGORY = '😺dzNodes/LayerFilter'
def film(self, image, center_x, center_y, saturation, vignette_intensity,
grain_power, grain_scale, grain_sat, grain_shadows, grain_highs,
blur_strength, blur_focus_spread, focal_depth,
depth_map=None
):
ret_images = []
for i in image:
i = torch.unsqueeze(i, 0)
_canvas = tensor2pil(i).convert('RGB')
if saturation != 1:
color_image = ImageEnhance.Color(_canvas)
_canvas = color_image.enhance(factor= saturation)
if blur_strength:
if depth_map is not None:
depth_map = tensor2pil(depth_map).convert('L').convert('RGB')
if depth_map.size != _canvas.size:
depth_map.resize((_canvas.size), Image.BILINEAR)
_canvas = depthblur_image(_canvas, depth_map, blur_strength, focal_depth, blur_focus_spread)
else:
_canvas = radialblur_image(_canvas, blur_strength, center_x, center_y, blur_focus_spread * 2)
if vignette_intensity:
# adjust image gamma and saturation
_canvas = gamma_trans(_canvas, 1 - vignette_intensity / 3)
color_image = ImageEnhance.Color(_canvas)
_canvas = color_image.enhance(factor= 1+ vignette_intensity / 3)
# add vignette
_canvas = vignette_image(_canvas, vignette_intensity, center_x, center_y)
if grain_power:
_canvas = filmgrain_image(_canvas, grain_scale, grain_power, grain_shadows, grain_highs, grain_sat)
ret_image = _canvas
ret_images.append(pil2tensor(ret_image))
log(f"{NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
return (torch.cat(ret_images, dim=0),)