3

I have a video and I'm trying to replicate some CSS filters for a video with FFMPEG.

Here is a screenshot from a video in CSS with the property filter: contrast(150%):

CSS Filtered contrast

I tried to recreate this effect in FFMPEG with the eq filter, setting contrast to 1.5

ffmpeg -y -i ./input.mp4 -vf "eq=contrast=1.5:brightness=0:saturation=1" -pix_fmt yuv420p ./filtered_input.mp4

And my output looks like this:

enter image description here

Here is an image of those two screenshots side by side:

enter image description here

You can see that the image on the left (filtered with CSS) is a little whiter / bluer if you look at the snow in between the images.

Here is a link to the original video: https://i.imgur.com/dDmp16s.mp4

I also found this comment here that discusses a relationship between contrast and saturation, but I found that there was a still a difference even if I adjusted the saturation, or even just adjusted the saturation by itself.

My meta point is that the eq filters by FFMPEG yield very different results from the corresponding CSS filters. Does anyone know why this might be happening, and how I can get them to match up?

3 Answers 3

5

My meta point is that the eq filters by FFMPEG yield very different results from the corresponding CSS filters. Does anyone know why this might be happening

There is no single consensus among all software providers of how brightness, contrast and saturation should work.

The CSS filters will have precise mathematical definitions, determined by the W3C. They need to be precise so that different browsers from different vendors can display the same rendered image. The current specification for CSS filters is here: https://www.w3.org/TR/filter-effects-1/

On the other hand, ffmpeg filters are implemented in an 'ad hoc' way by a collection of (very smart) engineers, and are not required to conform to any standard. They merely have to be useful in the view of the ffmpeg developers.

and how I can get them to match up?

I expect the only way to know exactly what an ffmpeg filter does is to read the source code (in other words, the source code is the specification). By doing that, you may be able to determine input parameters which will give you the same mathematical result as the CSS filters do. Or maybe not.

Since ffmpeg filters are not required to conform to any standard, there's a risk that a future ffmpeg update could change the result.

EDIT: Another thing to be wary of is that, even if the numerical colour values in both video files are the same, they might display differently when played. One reason is if metadata about the colour space was lost or changed during processing, so that the ffmpeg output is in a different colour space to the original video, causing the player to interpret the numerical colour values differently. Another reason is if one player supports colour space conversions that the other does not support. Based on the screenshots above, it looks like they are being viewed in different players (a browser vs something else). It would be best to view both videos in the same player.

4
  • Thanks for this, I wanted to use CSS filters to provide real-time visual updates on a video in the browser and then send the parameters back to FFMPEG to render. I have played with mapping the values but it did not work, Any ideas on other solutions? Mar 6, 2018 at 0:06
  • 1
    If I needed to do this, I would read the CSS filter specification at the above link, download the ffmpeg source, and implement my own ffmpeg filter which implemented the mathematical definitions of the CSS filters I needed for my website. The ffmpeg developer documentation explains how to do that, with simple templates to copy and paste from. If I felt particularly charitable I'd probably also offer the finished filter back to the ffmpeg community. Mar 7, 2018 at 3:00
  • No need to do all that. The eq filter has two routines that operate upon the pixel data. One of them is mathematically equivalent to CSS but is only activated if the user supplies an expression to change gamma. It's just a matter of allowing the user to select that codepath by choice, without altering gamma.
    – Gyan
    Mar 7, 2018 at 6:56
  • @Chungzuwalla thank you very much. I did find a workaround where I use a virtual browser to apply the CSS style to the image and then capture it as an image again. I will add a post here when its all up and running with some documentation on how I did it. Mar 8, 2018 at 9:39
1

I know this is a very old question, but figured I would contribute back and it's still very useful. I matched up CSS filter:brightness pretty well to ffmpeg using the colorlevels filter:

For CSS brightness values between 1 - 2 (Brighter) I used: colorlevels=rimax=" + brightness + ":gimax=" + brightness + ":bimax=" + brightness where "brightness" was translated to a value of .5 - 1 in the ffmpeg filter. For CSS brightness values between 0 - 1 (Darker) I used colorlevels=romax=" + brightness + ":gomax=" + brightness + ":bomax=" + brightness where "brightness" was used directly as a value of 0 - 1

This translated very well from ffmpeg to CSS brightness filter.

0

From another thread

filter: contrast(c) saturate(s);

is equivalent to

eq=contrast=c:saturation=c*s

Not sure about the brightness parameter.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .