Overlay¶
Puts clip overlay
on top of clip base
using different blend modes
, and
with optional x
, y
positioning, mask
operation and opacity
.
In some modes the input clips (
base
,overlay
andmask
) are converted to 4:4:4 internally. The output is re-converted to the input colorspace (or to theoutput
colorspace, if specified). But, if possible, original colorspace if preserved during the processing, such as in "blend", "luma" and "chroma" modes; seeuse444
, below.In general all clips are treated as full-range values. This means that numbers will not be clipped at TV range; you may use Limiter for this task afterwards. If your
mask
is TV-range, you should convert it to full-range, or the mask will never be fully opaque. You can use Histogram inHistogram("levels")
mode to view the color distributions. If your mask is of limited (TV) range, useConvertBits(fulls=false, fulld=true)
orColorYUV(levels="TV->PC
to upscale the color levels.It is not recommended to do overlays on interlaced material, unless you know what you are doing.
Syntax and Parameters¶
Overlay (clip, clip overlay, int "x", int "y", clip "mask", float "opacity",
string "mode", bool "greymask", string "output",
bool "ignore_conditional", bool "pc_range", bool "use444",
string "condvarsuffix")
- clip
This clip will be the base, and the overlay picture will be placed on top of this.
- overlay
This is the image that will be placed on top of the base clip. The colorspace or image dimensions do not have to match the base clip.
- x, y
These two variables define the placement of the overlay image on the base clip in pixels. The variable can be positive or negative.
Default: 0, 0
- mask
Optional transparency mask for the overlay image. Must be the same size as the overlay clip. Where mask is darker, overlay will be more transparent.
By default only the greyscale (luma) components are used, but this can be overridden with
greymask``=``false
.There is no default, but not specifying is equivalent to supplying a fully 255 (in general
2^bit_depth - 1
for 8-16 bit formats or1.0
for 32 bit float format) clip. Maximum pixel value means a 1.0 mask multiplier, that means full opacity.
- opacity
This will set how transparent your image will be. The value is from 0.0 to 1.0, where 0.0 is transparent and 1.0 is fully opaque (if no mask is used). When used together with a mask this value is multiplied by the mask value to form the final opacity.
Default: 1.0
- mode
Mode defines how your clip should be overlaid on your image.
Default: "Blend"
Mode |
Description |
|
---|---|---|
Blend |
![]() ![]() ![]() |
This is the default mode. When opacity is 1.0 and there is no mask the overlay image will be copied on top of the original. Ordinary transparent blending is used otherwise. |
Add |
![]() |
This will add the overlay video to the base video, making the video brighter. To make this as comparable to RGB, overbright luma areas are influencing chroma and making them more white. |
Subtract |
![]() |
The opposite of Add. This will make the areas darker. |
Multiply |
![]() |
This will also darken the image, but it works different than subtract. |
Chroma |
![]() |
This will only overlay the color information of the overlay clip on to the base image. |
Luma |
![]() |
This will only overlay the luminosity information of the overlay clip on to the base image. |
Lighten |
![]() |
This will copy the light infomation from the overlay clip to the base clip, only if the overlay is lighter than the base image. |
Darken |
![]() |
This will copy the light infomation from the overlay clip to the base clip, only if the overlay is darker than the base image. |
SoftLight |
![]() |
This will ligten or darken the base clip, based on the light level
of the overlay clip. If the overlay is darker than luma = 128 [ |
HardLight |
![]() |
This will ligten or darken the base clip, based on the light level of the overlay clip. If the overlay is darker than luma = 128, the base image will be darker. If the overlay is lighter than luma=128, the base image will be lighter. This is useful for adding shadows to an image. Painting with pure black or white results in pure black or white. |
Difference |
![]() |
This will display the difference between the clip and the overlay. Note that like Subtract a difference of zero is displayed as grey, but with luma=128 instead of 126. If you want the pure difference, use mode="Subtract" or add ColorYUV(off_y=-128). |
Exclusion |
![]() |
This will invert the image based on the luminosity of the overlay image. Blending with white inverts the base color values; blending with black produces no change. |
- greymask
Specifies whether chroma should be used for chroma transparency. Generally you want to leave this alone, this mode shouldn't be disabled. External filters like
mSharpen
andMasktools
are able to export proper chroma maps.Default: true
- output
It is possible to make Overlay return another colorspace. e.g. "YV24", "YUV420P14" or "RGB64"
Default: (input colorspace)
- ignore_conditional
Ignore any given conditional (runtime) variables.
See also: conditional variables section ColorYUV, or ConditionalReader or http://avisynth.nl/index.php/ColorYUV.
Default: false
- pc_range
When set to true, this will make all internal RGB→YUV →RGB conversions assume that YUV sources are full-range instead of the default TV range. It is only recommended to change this setting if you know what you are doing. See RGB considerations below.
Default: false
- use444
If set to false, Overlay uses conversionless mode where possible instead of going through YUV 4:4:4. However, for
Luma
andChroma
modes, RGB must be converted to YUV 4:4:4.Default: (adaptive)
false when mode="blend" and format is RGB
false when mode="blend", "luma" or "chroma" and format is YUV420/YUV422 (YV12/YV16). Original format is kept throughout the whole process, no 4:4:4 conversion occurs.
true for all other cases (input is converted internally to 4:4:4)
- condvarsuffix
Allows multiple filter instances to use differently named conditional parameters. Prevents collision and overwrite of variables which are used by different Overlay instances.
See also: conditional variables section ColorYUV, or ConditionalReader, or RGBAdjust.
How does it work: when reading the global variables, the
condvarsuffix
parameter is appended to the variable name. E.g. variable name "myvar_a" will be read instead of "myvar" whencondvarsuffix = "_a"
is provided.Useful for
ColorYUV
,RGBAdjust
,Overlay
when the conditional variables are enabled (or here, in Overlay, is not disabled).In the matching ConditionalReader one have to use the modified name as well:
ConditionalReader("overlay_a_offset.txt", "OL_opacity_offset", false, CondVarSuffix = "_a") # "_a" is added here by parameter
or specify the suffixed name directly:
ConditionalReader("overlay_a_offset.txt", "OL_opacity_offset_a", false) # "_a" is added here manually
Default: ""
RGB considerations¶
RGB inputs are accepted. However, Overlay for specific modes may convert the RGB clip
internally to 4:4:4 (see Avisynth+ exceptions), this will lead to an RGB→YUV conversion.
There are two modes for this conversion, toggled by the pc_range
parameter. This
parameter will extend the YUV range from 16-235 (8 bit example) (this is the range
used by all Avisynth converters) to 0-255. There are some cases where enabling
pc_range
is a good idea:
When overlaying an RGB clip using the
add
,subtract
ormultiply
modes, the range of the overlay clip is better, if it is 0-255, since this will enable completely dark areas not to influence the result (instead of adding 16 to every value).When NOT doing a colorspace conversion on output. If the output colorspace (RGB vs. YUV) is different from the input, the scale will be wrong. If
pc_range=true
, and input is RGB, while output is YV16, the YV16 will have an invalid range, and not CCIR-601 range.Planar RGB formats are also supported besides 8 bit packed RGB formats plus RGB48/RGB64.
"blend" mode keeps original RGB format, no YUV intermediate conversion is used.
Outputting RGB
It might be a good idea to let Overlay output YV24 or YUV444P10-16, even if your
input colorspace is RGB, as this avoids a colorspace conversion back to RGB from
YUV. You should however be aware that your material might be "overscaled", as
mentioned above, if you use pc_range=true
. You can correct this by using
ConvertBits(fulls=true, fulld=false)
or ColorYUV(levels="pc->tv")
to
convert back to 16-235 range (or equivalent ranges to 10+ bits).
Inputting RGB for mask clip
An RGB mask clip may behave a bit oddly if it contains color information.
If you use a greyscale mask
, or if you leave greymask=true
, you will get
the result you would expect. Note that mask values are never scaled, so it
will automatically be in full-range, directly copied from the RGB values.
Traditionally, the mask is retrieved from channel "B" (Blue).
Using RGB32, RGB64 or planar RGBA alpha channel
Overlay ignores the alpha (transparency) channel in an RGB32 clip. If you
want the alpha, you can use something like
Overlay(kitten, mask=kitten.ExtractA())
or
Overlay(kitten, mask=kitten.ShowAlpha("RGB32"))
.
See also Extract filters and ShowAlpha.
Repeated overlays on RGB base clip
When doing repeated partial overlays on an RGB base clip, the unchanged parts of the base clip may undergo a RGB→YV24→RGB conversion for each call to Overlay, producing a progressive loss of color accuracy. In these situations, it is better to convert the base clip to 4:4:4 format (e.g. YV24) before doing the overlays and convert back to RGB afterwards. Remember, that "Blend" does not convert from RGB.
Conditional Variables¶
The global variables OL_opacity_offset
, OL_x_offset
and
OL_y_offset
are read each frame, and applied. It is possible to modify
these variables using FrameEvaluate. The values of these variables
will be added to the original on each frame. So if you specify "x = 100" as a
filter parameter, and the global variable OL_x_offset
is set to 50, the
overlay will be placed at x = 150.
If you need to use conditional variables in multiple filters, use
condvarsuffix
parameter to make them unique for each filter instance.
In other Overlay filters this can even be disabled by using the
ignore_conditional = true
parameter.
There is an example of conditional modification at the ConditionalReader page.
Examples¶
# Prepares some sources.
bg = ColorBars(512,384).ConvertToYUY2
text = BlankClip(bg).Subtitle("Colorbars", size=92,
\ text_color=$ffffff).ColorYUV(levels="tv->pc")
# Overlay the text in three different versions.
return Overlay(bg, text, x=50, y=20, mode="subtract", opacity=0.25)
return Overlay(text, x=50, y=120, mode="add", opacity=0.5)
return Overlay(text, x=50, y=240, mode="blend", opacity=0.7)
# Overlay yuy2 clip with rgb clip using a yuy2 mask
# (note that the luma range of the mask is [0-255]).
return Overlay(yuy2clip, rgbclip, mask=rgbclip.ShowAlpha("yuy2"))
# ...which is the same as
mask = rgbclip.ShowAlpha("rgb").ConvertToYUY2
\ .ColorYUV(levels="TV->PC")
return Overlay(yuy2clip, rgbclip, mask=mask)
# ...which is the same as
mask = rgbclip.ShowAlpha("rgb")
return Overlay(yuy2clip, rgbclip, mask=mask)
This will take the average of two clips. It can be used for example to combine two captures of different broadcast captures for reducing noise. A discussion of this idea can be found [here]. A sample script (of course you have to ensure that the frames of the two clips matches exactly, using Trim as needed):
clip1 = AviSource("F:\shakira-underneath_your_clothes1.avi")
clip2 = AviSource("F:\shakira-underneath_your_clothes2.avi")
Overlay(clip1, clip2, mode="blend", opacity=0.5)
Another use is to detect an altered video using Video Error Level Analysis (VELA), where clip2 is clip1 resaved using an h.263 Codec (e.g. XVID). This method is effective when the suspected altered video (clip1) has not been resaved multiple times. Levels is used to exaggerate contrast for view-ability:
clip1 = AviSource("SuspectVideo.avi")
clip2 = AviSource("SuspectVideo_resaved.avi")
result= Overlay(clip1,clip2,mode="Subtract").Levels(0, 5.0, 100, 0, 255)
Use a blue (or any other color) background (blue.jpg is a blue frame overlaid with subtitles in a black rectangle) as mask. The black rectangle containing the subtitles will be visible on the source clip (which is ColorBars here):
testcard = ColorBars()
# get a blue mask clip (the same blue as in ColorBars is used: R16 G16 B180)
maskclip = BlankClip(testcard, color=$0f0fb4)
# Example subtitle file with blue backgroud as above
subs = ImageSource("F:\TestClips\blue.jpg").ConvertToRGB32
maskclip = ColorKeyMask(subs, $0f0fb4, 60)
Overlay(testcard, subs, mask=ShowAlpha(maskclip), mode="blend", opacity=1)


A tolerance of 60 is used here because the blue is not entirely uniform. Near the black rectangles the blue is given by R23 G22 B124. Probably due to the compression of blue.jpg.
Move a red (or any other color) dot on a clip using
ConditionalReader
(dot.bmp is a red dot on a black background):
a1 = ColorBars().Trim(0,399)
a2 = ImageSource("F:\TestClips\dot.bmp").ConvertToRGB32
# a2.GreyScale returns a grey dot on a black background; Levels makes the dot white
mask_clip = Mask(a2, a2.GreyScale.Levels(0, 1, 75, 0, 255))
Overlay(a1, a2, mask=ShowAlpha(mask_clip), y=0, x=0, mode="blend", opacity=1)
ConditionalReader("xoffset.txt", "ol_x_offset", false)
ConditionalReader("yoffset.txt", "ol_y_offset", false)
Make xoffset.txt containing the x-positions and yoffset.txt containing the y-positions of the moving dot (see ConditionalReader for more info), and put it in the same folder as your script:
xoffset.txt
Type int
Default -50
R 0 100 20
I 100 200 20 250
R 200 300 250
I 300 400 250 400 ::yoffset.txt
Type int
Default -50
R 0 100 20
I 100 200 20 350
R 200 300 350
I 300 400 350 40


thus the dot moves in the following way: (20,20) -> (250,350) -> (400,40). Nb, it's also possible to do this with Animate.
And the same with using condvarsuffix
:
a1 = ColorBars().Trim(0,399)
a2 = ImageSource("F:\TestClips\dot.bmp").ConvertToRGB32
# a2.GreyScale returns a grey dot on a black background; Levels makes the dot white
mask_clip = Mask(a2, a2.GreyScale.Levels(0, 1, 75, 0, 255))
Overlay(a1, a2, mask=ShowAlpha(mask_clip), y=0, x=0, mode="blend", opacity=1, \
condvarsuffix="_a")
# directly read the _a prefixed variable
ConditionalReader("xoffset.txt", "ol_x_offset_a", false)
# or _a as exactly named parameter
ConditionalReader("yoffset.txt", "ol_y_offset", false, condvarsuffix="a")
Changelog |
|
---|---|
3.7.2 |
Address issue #255: "blend": now using accurate formula using float calculation. |
3.7.1 |
Overlay mode "multiply": overlay clip is not converted to 4:4:4 when when 420 or 422, since only Y is used from it (speed). |
3.7.0 |
allow 4:1:1 input
fix crash when mask is YUV411 and greymask=false
|
3.4.0 |
Add "condvarsuffix" parameter |
r2502 |
Correct masked blend: keep exact clip1 or clip2 pixel values for mask extremes 255 or 0. Previously 0 became 1 for zero mask, similarly 255 changed into 254 for full transparency (255) mask |
r2420 |
"Blend" native greyscale mode: process y plane only w/o conversion
automatic use444=false for "blend"/"luma"/"chroma"
for inputs: 420/422/444 and any RGB, lossless Planar RGB intermediate
for PackedRGB.
mask auto-follows input clip format. For compatibility: when
greymask=true (default) and mask is RGB then mask source is
the B channel 254 for full transparency (255) mask
|
r2359 |
new parameter: bool use444 (default true for compatibility)
lossless RGB "blend" w/o YUV conversion
|
v2.54 |
Initial Release |
$Date: 2025/03/15 21:16:50 $