FFMPEG blending comes out looking grayscale rather than colourful - ffmpeg

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 ?

Related

ffmpeg blend=screen makes background look green or foreground green

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"

How to draw a white box on image using FFMpeg correctly

I want to draw some white filled rectangles in a bitmap (bmp format, happens with other input formats too) and store it as JPEG (mjpeg) with FFMpeg console executable on Windows 10 64-bit.
Therefore I use the drawbox filter. If I take any color which is not "next to white", it works fine. If I try to draw white boxes I always get grey boxes. If I use another output format like PNG it works fine.
It does not matter if I use the string White or a hex RGB(A) format like 0xFFFFFF or 0xFFFFFFFF. Even colors "next to white" like 0xFEFEFE do always result in grey color.
FFMpeg does not report any warnings or errors. I use following command line:
ffmpeg.exe -i input.bmp -filter:v drawbox=x=10:y=10:w=100:h=100:color=0xFFFFFF:t=fill -q:v 3 -f image2 output.jpg
I can confirm that this issue happens with the latest development version (master branch).
I am doing something wrong here or is this a bug?
OS: Win10 64-Bit, latest FFMpeg from https://www.gyan.dev/ffmpeg/builds/ (master branch)

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

how to convert png animation to gif and keep the transparent using ffmpeg

I would like to convert png animation file to gif in windows,
I choose to use ffmpeg, as I have many of pngs to covert, cmd is quite straight forward in this case.
the sample img here:
https://i.imgur.com/SPGGMEb.png
tried:
ffmpeg -i SPGGMEb.png -vocdec gif output.gif
everything seems fine but the transparent background turns to black, as:
https://i.stack.imgur.com/7CbO8.gif
how can I keep the transparent background during conversion?

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.

Resources