feat: blur適用
This commit is contained in:
parent
c0ad2a551d
commit
0c9b646690
|
|
@ -132,17 +132,24 @@ def setup_strip_compositor_modifier(
|
||||||
name="FaceMaskBlur",
|
name="FaceMaskBlur",
|
||||||
type='COMPOSITOR',
|
type='COMPOSITOR',
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set the node tree
|
# Set the node tree/group (Blender 5.0 uses node_group instead of node_tree)
|
||||||
modifier.node_tree = node_tree
|
if hasattr(modifier, 'node_group'):
|
||||||
|
# Blender 5.0+
|
||||||
|
modifier.node_group = node_tree
|
||||||
|
elif hasattr(modifier, 'node_tree'):
|
||||||
|
# Blender 4.x
|
||||||
|
modifier.node_tree = node_tree
|
||||||
|
else:
|
||||||
|
raise AttributeError("Compositor modifier has neither 'node_group' nor 'node_tree' attribute")
|
||||||
|
|
||||||
# Configure input mapping
|
# Configure input mapping
|
||||||
# The modifier automatically maps strip image to first input
|
# The modifier automatically maps strip image to first input
|
||||||
# We need to configure the mask input
|
# We need to configure the mask input
|
||||||
|
|
||||||
# TODO: Blender 5.0 may have different API for this
|
# TODO: Blender 5.0 may have different API for this
|
||||||
# This is a placeholder for the actual implementation
|
# This is a placeholder for the actual implementation
|
||||||
|
|
||||||
return modifier
|
return modifier
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ import bpy
|
||||||
from bpy.props import FloatProperty, IntProperty, StringProperty
|
from bpy.props import FloatProperty, IntProperty, StringProperty
|
||||||
from bpy.types import Operator
|
from bpy.types import Operator
|
||||||
|
|
||||||
from ..core.compositor_setup import get_or_create_blur_node_tree, setup_strip_compositor_modifier
|
|
||||||
|
|
||||||
|
|
||||||
class SEQUENCER_OT_apply_mask_blur(Operator):
|
class SEQUENCER_OT_apply_mask_blur(Operator):
|
||||||
"""Apply blur effect using mask strip."""
|
"""Apply blur effect using mask strip."""
|
||||||
|
|
@ -63,7 +61,7 @@ class SEQUENCER_OT_apply_mask_blur(Operator):
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
seq_editor = context.scene.sequence_editor
|
seq_editor = context.scene.sequence_editor
|
||||||
video_strip = seq_editor.active_strip
|
video_strip = seq_editor.active_strip
|
||||||
|
|
||||||
# Find mask strip
|
# Find mask strip
|
||||||
if not self.mask_strip_name:
|
if not self.mask_strip_name:
|
||||||
# Try to find auto-generated mask
|
# Try to find auto-generated mask
|
||||||
|
|
@ -73,34 +71,119 @@ class SEQUENCER_OT_apply_mask_blur(Operator):
|
||||||
else:
|
else:
|
||||||
self.report({'ERROR'}, "Please select a mask strip")
|
self.report({'ERROR'}, "Please select a mask strip")
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
mask_strip = seq_editor.strips.get(self.mask_strip_name)
|
mask_strip = seq_editor.strips.get(self.mask_strip_name)
|
||||||
if not mask_strip:
|
if not mask_strip:
|
||||||
self.report({'ERROR'}, f"Mask strip not found: {self.mask_strip_name}")
|
self.report({'ERROR'}, f"Mask strip not found: {self.mask_strip_name}")
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Try using Compositor Modifier (preferred method)
|
# Use Mask Modifier approach (Blender 5.0 compatible)
|
||||||
self._apply_with_modifier(context, video_strip, mask_strip)
|
self._apply_with_mask_modifier(context, video_strip, mask_strip)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.report({'ERROR'}, f"Failed to apply blur: {e}")
|
self.report({'ERROR'}, f"Failed to apply blur: {e}")
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def _apply_with_modifier(self, context, video_strip: "bpy.types.Strip", mask_strip: "bpy.types.Strip"):
|
def _apply_with_mask_modifier(self, context, video_strip: "bpy.types.Strip", mask_strip: "bpy.types.Strip"):
|
||||||
"""Apply blur using Compositor Modifier."""
|
"""
|
||||||
# Get or create the blur node tree
|
Apply blur using Mask Modifier.
|
||||||
node_tree = get_or_create_blur_node_tree(blur_size=self.blur_size)
|
|
||||||
|
Workflow:
|
||||||
# Add compositor modifier to the video strip
|
1. Duplicate the video strip
|
||||||
modifier = setup_strip_compositor_modifier(
|
2. Create Gaussian Blur effect on the duplicate
|
||||||
strip=video_strip,
|
3. Add Mask modifier to the blur effect (references mask strip)
|
||||||
mask_strip=mask_strip,
|
4. Composite with Alpha Over effect
|
||||||
node_tree=node_tree,
|
"""
|
||||||
|
seq_editor = context.scene.sequence_editor
|
||||||
|
|
||||||
|
# Find available channels
|
||||||
|
used_channels = {s.channel for s in seq_editor.strips}
|
||||||
|
duplicate_channel = video_strip.channel + 1
|
||||||
|
while duplicate_channel in used_channels:
|
||||||
|
duplicate_channel += 1
|
||||||
|
|
||||||
|
blur_channel = duplicate_channel + 1
|
||||||
|
while blur_channel in used_channels:
|
||||||
|
blur_channel += 1
|
||||||
|
|
||||||
|
composite_channel = blur_channel + 1
|
||||||
|
while composite_channel in used_channels:
|
||||||
|
composite_channel += 1
|
||||||
|
|
||||||
|
# Step 1: Duplicate the video strip
|
||||||
|
if video_strip.type == 'MOVIE':
|
||||||
|
video_copy = seq_editor.strips.new_movie(
|
||||||
|
name=f"{video_strip.name}_copy",
|
||||||
|
filepath=bpy.path.abspath(video_strip.filepath),
|
||||||
|
channel=duplicate_channel,
|
||||||
|
frame_start=video_strip.frame_final_start,
|
||||||
|
)
|
||||||
|
elif video_strip.type == 'IMAGE':
|
||||||
|
# For image sequences, duplicate differently
|
||||||
|
video_copy = seq_editor.strips.new_image(
|
||||||
|
name=f"{video_strip.name}_copy",
|
||||||
|
filepath=bpy.path.abspath(video_strip.elements[0].filename) if video_strip.elements else "",
|
||||||
|
channel=duplicate_channel,
|
||||||
|
frame_start=video_strip.frame_final_start,
|
||||||
|
)
|
||||||
|
# Copy all elements
|
||||||
|
for elem in video_strip.elements[1:]:
|
||||||
|
video_copy.elements.append(elem.filename)
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unsupported strip type: {video_strip.type}")
|
||||||
|
|
||||||
|
# Match strip length
|
||||||
|
strip_length = video_strip.frame_final_end - video_strip.frame_final_start
|
||||||
|
video_copy.frame_final_end = video_copy.frame_final_start + strip_length
|
||||||
|
|
||||||
|
# Step 2: Create Gaussian Blur effect on the duplicate
|
||||||
|
blur_effect = seq_editor.strips.new_effect(
|
||||||
|
name=f"{video_strip.name}_blur",
|
||||||
|
type='GAUSSIAN_BLUR',
|
||||||
|
channel=blur_channel,
|
||||||
|
frame_start=video_strip.frame_final_start,
|
||||||
|
length=strip_length,
|
||||||
|
input1=video_copy,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.report({'INFO'}, f"Applied blur with Compositor Modifier")
|
# Set blur size (Blender 5.0 API)
|
||||||
|
if hasattr(blur_effect, 'size_x'):
|
||||||
|
blur_effect.size_x = self.blur_size
|
||||||
|
blur_effect.size_y = self.blur_size
|
||||||
|
elif hasattr(blur_effect, 'size'):
|
||||||
|
blur_effect.size = self.blur_size
|
||||||
|
|
||||||
|
# Step 3: Add Mask modifier to the blur effect
|
||||||
|
mask_mod = blur_effect.modifiers.new(
|
||||||
|
name="FaceMask",
|
||||||
|
type='MASK'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Set mask input (Blender 5.0 API)
|
||||||
|
if hasattr(mask_mod, 'input_mask_strip'):
|
||||||
|
mask_mod.input_mask_strip = mask_strip
|
||||||
|
elif hasattr(mask_mod, 'input_mask_id'):
|
||||||
|
mask_mod.input_mask_type = 'STRIP'
|
||||||
|
mask_mod.input_mask_id = mask_strip
|
||||||
|
|
||||||
|
# Step 4: Composite with Alpha Over effect
|
||||||
|
alpha_over = seq_editor.strips.new_effect(
|
||||||
|
name=f"{video_strip.name}_composite",
|
||||||
|
type='ALPHA_OVER',
|
||||||
|
channel=composite_channel,
|
||||||
|
frame_start=video_strip.frame_final_start,
|
||||||
|
length=strip_length,
|
||||||
|
input1=video_strip, # Base (original)
|
||||||
|
input2=blur_effect, # Blurred with mask
|
||||||
|
)
|
||||||
|
|
||||||
|
# Hide intermediate strips (but keep them active)
|
||||||
|
video_copy.mute = True
|
||||||
|
mask_strip.mute = True
|
||||||
|
|
||||||
|
self.report({'INFO'}, f"Applied blur with Mask Modifier (composite on channel {composite_channel})")
|
||||||
|
|
||||||
def _apply_with_meta_strip(self, context, video_strip: "bpy.types.Strip", mask_strip: "bpy.types.Strip"):
|
def _apply_with_meta_strip(self, context, video_strip: "bpy.types.Strip", mask_strip: "bpy.types.Strip"):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user