moviepy
moviepy copied to clipboard
Adding Blend with pillow ops
I'm using a modified version of the 'blit_on' function to use PIL's overlay modes (Channel Operations Module) between different video layers in CompositeVideoClip. I understand that this feature has been considered (added/removed) several times in the project. I hope you can consider this addition as valuable:
Modifications to the VideoClip.py file:
@outplace
def with_mode(self, mode, scale=1.0, offset=0):
"""Set the clip's layer mode in compositions.
Using Blend Modes of Pillow images called ImagesChops ("Channel Operations").
Note: Only has effect when the clip is used in a CompositeVideoClip.
"""
mode_without_option=["normal", "add_modulo", "darker", "difference", "lighter",
"logical_and", "logical_or", "logical_xor", "multiply", "soft_light", "hard_light",
"overlay", "screen", "substract_modulo"]
mode_with_scale_offset=["add", "substract"]
if isinstance(mode, str):
if mode in mode_with_scale_offset:
self.mode_scale = scale
self.mode_offset = offset
if self.mask is not None:
self.mask.mode_scale = scale
self.mask.mode_offset = offset
else:
if mode not in mode_without_option:
raise ValueError("Unknown mode in Pillow ImageChops")
self.mode = mode
if self.mask is not None:
self.mask.mode = mode
else:
raise ValueError("Select mode into available Pillow ImageChops :", mode_without_option+mode_with_scale_offset)
def blit_on(self, picture, t):
"""Returns the result of the blit of the clip's frame at time `t`
on the given `picture`, the position of the clip being given
by the clip's ``pos`` attribute. Meant for compositing.
"""
.
.
.
.
# Blend Channel Mode
if self.mode not in ["normal"]:
if picture.size != im_img.size:
im_pic_bg = picture.crop((pos[0], pos[1], pos[0]+wi, pos[1]+hi))
else:
im_pic_bg = picture
modeFct = getattr(ImageChops, self.mode)
if self.mode in ["add", "substract"]:
im_img = modeFct(im_pic_bg, im_img, scale=self.mode_scale, offset=self.mode_offset)
else:
im_img = modeFct(im_pic_bg, im_img)
picture.paste(im_img, pos, im_mask)
return picture
Example of use :
myvideo = VideoFileClip("clip.mp4")
txt = TextClip(text="Text", method="caption", font="Montserrat-Black-Italic", font_size=60, color="#76C0FF")
txt = txt.with_duration(myvideo.duration)\
.with_position("center")\
.with_opacity(1.0)\
.with_mode("screen")
CVP = CompositeVideoClip([myvideo, txt])
CVP.write_videofile("withtxt.mp4", fps=25)
Mode "add modulo":
Mode "difference":
Mode "soft_light":
Tell the example usages.