Log in

View Full Version : How can I render subtitle on a fully transparent RGB32 video?


konstantin1
20th August 2021, 01:14
I would like to animate a subtitle from right to left, by animating the "overlay" or "layer" x parameter.

I have the following AviSynth script:


b=blackness(color=$00000000,pixel_type="RGB32").subtitle("Subs on transparent video",size=30,align=5)
b


The result is:
https://i.imgur.com/CAS9GzE.png

The subtitle is clearly visible.

But when I would like to overlay the transparent video on top of a background, a problem arises:


b=blackness(color=$00000000,pixel_type="RGB32").subtitle("Subs on transparent video",size=30,align=5)
v=version().bilinearresize(b.width,b.height).converttorgb32()
v.overlay(b,mask=b.showalpha())

The result is:
https://i.imgur.com/SxnVIqC.png

Only the background is visible, the subtitle is missing. The result is the same, if I use "layer" instead of "overlay". One would expect that the subtitle should be visible, on top of the background.

However if I use "merge", the subtitle becomes visible again:
https://i.imgur.com/dpnL04t.png

What's going on here? How can I achieve that the subtitle appear when I make overlay operation with the transparent layer on the background?

StainlessS
20th August 2021, 02:08
Beats the hell out of me :(

konstantin1
20th August 2021, 02:30
The "subtitle" filter doesn't modify the alpha channel, it should be constructed somehow manually.

Now I have some result, but far from optimal:

b=blackness(color=$00000000,pixel_type="RGB32").subtitle("Subs on transparent video",size=50,align=5)
b_patched=mergeargb(merge(extractr(b),extractg(b)).merge(extractb(b)),extractr(b),extractg(b),extractb(b))
v=version().bilinearresize(b.width,b.height).converttorgb32()
v.overlay(b_patched,mask=b_patched.showalpha())
subtitle("Subs on transparent video",size=50,align=2)


And the image:
https://i.imgur.com/VWDBSVJ.png


The lower subtitle line shows how it should look properly. The centered one is a bit transparent, what is suboptimal now.

poisondeathray
20th August 2021, 02:50
You can specify "white" for subs, and use that as a mask layer. Don't forget the halo color

See gavino's reply
https://forum.doom9.org/showthread.php?t=160891

konstantin1
20th August 2021, 02:52
Result is even better with "levels"


b=blackness(color=$00000000,pixel_type="RGB32").subtitle("Subs on transparent video",size=50,align=5)
b_patched=mergeargb(merge(extractr(b),extractg(b)).merge(extractb(b)).levels(0,1.0,80,0,255),extractr(b),extractg(b),extractb(b))
v=version().bilinearresize(b.width,b.height).converttorgb32()
v.overlay(b_patched,mask=b_patched.showalpha())
subtitle("Subs on transparent video",size=50,align=2)


https://i.imgur.com/KvVpmYV.png

konstantin1
20th August 2021, 03:15
Now the result looks fine, however the subtitles need to rendered twice: once on a transparent, black surface, and then on a fully opaque white surface, and finally using colorkeymask to determine the correct alpha channel:


b=blackness(color=$00000000,pixel_type="RGB32").subtitle("Subs on transparent video",size=50,align=5)
bi=blackness(color=$ffffffff,pixel_type="RGB32").subtitle("Subs on transparent video",size=50,align=5).invert()
v=version().bilinearresize(b.width,b.height).converttorgb32()
v.overlay(b,mask=bi.colorkeymask($000000,0,0,0))
subtitle("Subs on transparent video",size=50,align=2)


An the result, the two subtitle lines looks identical:

https://i.imgur.com/ZDb9u5x.png

konstantin1
20th August 2021, 03:20
unfortunately doesn't work if the text is white.

Gavino
24th August 2021, 18:14
It does work for white text too, as long as you only set the color of the first Subtitle() call.
b=blackness(color=$00000000,pixel_type="RGB32").subtitle("Subs on transparent video",size=50,align=5,text_color=color_white)
bi=blackness(color=$ffffffff,pixel_type="RGB32").subtitle("Subs on transparent video",size=50,align=5).invert()
v=version().bilinearresize(b.width,b.height).converttorgb32()
v.overlay(b,mask=bi.colorkeymask($000000,0,0,0))
The second call (affecting the mask) still needs to use the default color (or in fact anything but white!).

But I think the method I suggested (mentioned by poisondeathray) is a bit simpler and clearer.
text = "Subs on transparent video"
b=blackness(color=$00000000,pixel_type="RGB32").subtitle(text,size=50,align=5) #set color here also if required
v=version().bilinearresize(b.width,b.height).converttorgb32()
v.overlay(b,mask=b.ShowAlpha().Subtitle(text,size=50,align=5, text_color=color_white, halo_color=color_white))
Here the mask under the subtitle is explicitly set to white (RGB $ffffff), ie fully opaque, letting the title show.