ffmpeg blend=screen makes background look green or foreground green - ffmpeg

When I apply a screen blend to the foreground asset (Pikachu) over the background asset (White circle on black background)
GIMP and Adobe Photoshop make the circle asset look white, and the background asset look RGB like this:-
which is how it should look.
However, if we take the input assets:-
and
and use this ffmpeg command
ffmpeg -i circle_rgb_50.png -i pikachu_rgb.png -filter_complex "[0:v][1:v]blend=screen" pikachu_screened_over_circle_rgb_just_blend.png
we get this:-
and if I reverse the blend so that the inputs to the blend function are the other way around, like this:-
ffmpeg -i circle_rgb_50.png -i pikachu_rgb.png -filter_complex "[1:v][0:v]blend=screen" pikachu_screened_over_circle_rgb_just_blend_other_way_around.png
we get this:-
Why doesn't FFMPEG do blending the same way as GIMP or Adobe Photoshop ?
Or is there another parameter I need to pass so that blends look as they should ?

screen is the value of all_mode option of the blend filter. Correct your filter_complex:
-filter_complex "[0:v][1:v]blend=all_mode=screen"

Related

How to draw a text with perspective using ffmpeg

I need to add a text to a video using ffmpeg and it needs to be with perspective like in the image.
img
i have tried with perspective but i get perspective into the whole video not only the text.
How can i do this?
You want to add a text overlay, so your best option is to pick a perspective font and use that, with the drawtext filter.
Here's an example with the font Therp. It isn't perfect but might point you in the right direction.
ffmpeg -i input.mp4 -vf "drawtext=fontfile=./.fonts/Therp.ttf:text='Perspective': x=300: y=300:font='Therp Regular':fontsize=40:fontcolor=white:" -c:a copy -f matroska - | ffplay -autoexit -i -
Result:

FFMPEG blending comes out looking grayscale rather than colourful

When i do a blend of two pngs, it comes out looking grayscale whereas it should have colour.
These are the two PNG input assets that I then create MP4s from:-
Here is the command:-
ffmpeg -i black_circle.png -i pikachu.png -filter_complex "[0:v]setsar=sar=1,format=rgb24[rgb1];[1:v]setsar=sar=1,format=rgb24[rgb2];[rgb1]split[out1_1][out1_2];[out1_1]crop=50:50:0:0:exact=1,setsar=1[cropped1];[cropped1][rgb2]blend=screen[blended1];[out1_2][blended1]overlay=0:0" pikachu_screened_on_circle_rgb.png
And here is the output:-
However, Pikachu should retain his Red, Green and Blue, but instead Pikachu looks grayscale.
I was wondering why this is ?
And what i need to do so that Pikachu retains his yellow skin, and rosey cheeks ?
So I thought initially that it might be something to do with the white and black circle being a grayscale asset. But then I replaced the black and white circle with this asset:-
and I saw that when something is black FFMPEG makes it grayscale:-
The command using these two assets instead is this:-
ffmpeg -i rgb_backing.png -i pikachu.png -filter_complex "[0:v]setsar=sar=1,format=rgb24[rgb1];[1:v]setsar=sar=1,format=rgb24[rgb2];[rgb1]split[out1_1][out1_2];[out1_1]crop=50:50:0:0:exact=1,setsar=1[cropped1];[cropped1][rgb2]blend=screen[blended1];[out1_2][blended1]overlay=0:0" pikachu_screened_on_rgb_backing.png
Is there a way to invert black to white in FFMPEG ?

Adding an image in the padding area of the video instead of black color using FFMPEG

I have some videos of resolution 1280 X 720 with black padding area in both left and right side around the display area of all videos. I want to display a static image in padding area of video instead of solid black color. I am working with FFMPEG library but can't find any way to do so. Can you please help me regarding this?
Thank You!
Use the cropdetect filter to determine crop parameters to remove the black. See Remove black bars using ffmpeg for an example of how to get the crop parameters.
Crop the black area and overlay the video over the image:
ffmpeg -i video.mp4 -i background.jpg -filter_complex "[0]crop=404:720:438:0[vid];[1][vid]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" -c:a copy output.mp4
Well, after trying some commands I made a command to do so and its working for me.
ffmpeg -loop 1 -i image.jpg -i video.mp4 -filter_complex "[1:v]scale=1280:720:force_original_aspect_ratio=decrease:-1[fg];[0:v][fg]overlay=(W-w)/2:(H-h)/2:shortest=1" output.mp4

Overlay text on video with ffmpeg [duplicate]

It is described here how ot burn a srt file into a video.
However, I want to put a semi-transparent background to the subtitles so that the texts can be read more easily. How can I do that?
ASS subtitles can have a semi-transparent background for the text.
With aegisub
The easiest way to do this is with aegisub.
Open your subtitles file with aegisub.
Click Subtitle → Styles manager.
Under Current Script choose Default, then press the Edit button.
Experiment with the Outline and Shadow values. Check Opaque box.
Under Colors click the color under Outline or Shadows. A window will appear. Adjust the value of the Alpha box to change transparency.
Save the subtitles as an .ass file.
Now you can use the AAS file to make hardsubs or softsubs with ffmpeg.
Without aegisub
If you want hardsubs you can use the subtitles filter to add the transparent background with the force_style option.
ffmpeg -i input -filter_complex "subtitles=subs.ass:force_style='OutlineColour=&H80000000,BorderStyle=3,Outline=1,Shadow=0,MarginV=20'" output
This will work with any text based subtitles supported by FFmpeg because the filter will automatically convert them to ASS.
See SubStation Alpha (ASS) style fields for formatting options.
Issue with multiple lines
If your subtitles contains multiple lines, due to auto-wrapping of long lines or an intentional line break, the backgrounds will overlap and potentially look ugly as shown below:
You can avoid this by:
Changing the Outline and Shadow sizes to 0.
The alpha settings of the shadow will control the transparency of the background box. Click on the shadow color to adjust the Alpha of the shadow color to your desired transparency level.
Edit the ASS file in a text editor. In the Style line change the value corresponding with BorderStyle to 4. This will fill the bounding box background of each subtitle event. Example Style line:
Style: Default,Arial,20,&H00FFFFFF,&H000000FF,&H80000000,&H80000000,-1,0,0,0,100,100,0,0,4,0,0,2,10,10,10,1
Example:
Note that BorderStyle=4 is a non-standard value, so it may not work properly in all players.
Thanks to sup and wm4 for the BorderStyle suggestion.
Using drawbox
The drawbox filter can be used to create a background box.
This may be useful if you want the box to span the width.
ffmpeg -i input -filter_complex "drawbox=w=iw:h=24:y=ih-28:t=max:color=black#0.4,subtitles=subs.ass" output
Downside is that you have to account for line breaks or word wrapping for long subtitles. Simply making the box taller to compensate will suffice, but will look ugly because the subtitles baseline remains static: the single line subtitles will have more padding on the top than the bottom.
Create a png with a transparent box and a alpha channel in your favoured size. You can use e.g. gimp or photoshop.
Then use this command:
ffmpeg -i video.mp4 -i logo.png -filter_complex "[0:v][1:v]overlay=10:10" \
-codec:a copy out.mp4
where 10:10 is the distance from the upper left corner.
After that you can insert your subtitles.
ffmpeg -i input.mp4 -filter_complex "subtitles=input.srt:force_style='BackColour=&H80000000,BorderStyle=4,Fontsize=11'" output.mp4
BackColour=&H80000000 means having a %50 opaque black background.
Its a hex representation of color, AABBGGRR.
You can use this Aegisub script. This script automatically generate transparent background for every line of subtitle.
With the current version of libass (0.15) and the current version of ffmpeg (N-100402-g0320dab265, compiled from source, probably the same as version 4.2), you can use this bash script
INFILE="movie.mp4"
SUBS="subtitles.srt"
OUTFILE="result.mp4"
ffmpeg -i "${INFILE}" -vf subtitles=${SUBS}:force_style='Borderstyle=4,Fontsize=16,BackColour=&H80000000'" "${OUTFILE}"
to burn subtitles.srt into movie.mp4 and save it as result.mp4.
The subtitles will appear correctly boxed in a 50% transparent rectangle,
even when there are 2 lines in a subtitle.

ffmpeg animated gif is blotchy

I am generating an animated gif from an mp4 ... but due (I think) to color reduction (gif requires -pix_fmt rgb24) the result is somewhat ... blotchy? like running an image through an oil paint (or maybe "posterize") special effect filter. I think that the quality could be better, but I don't know what to tweak.
Not sure about this ... but ooking at the color palette of the resulting gif in an image editor it does not even appear to have attempted to create a color palette specific to this clip, but instead is attempting to us a generic palette ... which wastes a lot of pixmap space. That is, if I am interpreting this correctly.
Any tips on preserving the original video image instead of getting a "posterized" animated gif?
To get better looking gifs, you can use generated palettes. palettegen filter will generate a png palette to use with the paletteuse filter.
ffmpeg -i input.mkv -vf palettegen palette.png
ffmpeg -i input.mkv -i palette.png -lavfi paletteuse output.gif
You can try using -vf format=rgb8,format=rgb24.

Resources