Reputation: 6483
Context
I am working on a browser extension, Night Video Tuner, which injects SVG filters into HTML pages using Javascript, in order to filter out blue light from videos. Here is an example of what an SVG filter generated by the extension would look like:
<svg xmlns="http://www.w3.org/2000/svg">
<filter id="temperature_filter" style="display: none;">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 0.6949030005552019 0 0 0 0 0 0.4310480202110507 0 0 0 0 0 1 0"></feColorMatrix>
</filter>
</svg>
style="display: none;"
is used to prevent the SVG element from affecting the layout of the page.
I am adding a filter: url(#temperature_filter)
property to the style attribute of any video element found in the current HTML page in order to apply this SVG filter to the media content. Here is a small Fiddle showcasing a similar setup, with a video and its filter applied to it.
Issue
So far this approach is working like a charm on Chrome and Opera. Unfortunately, due to a bug in Firefox, I cannot use the style="display: none;"
property for that browser and am looking into applying workarounds suggested by this other Stack Overflow question instead.
I noticed that the overall quality of the SVG filter is significantly degraded in Firefox, with visual artifacts appearing, especially in darker parts of the video. This is also the case when I remove style="display: none;"
from the filter in Opera and Chrome, which suggests that this property is linked to the filter no longer rendering properly. Here is an example, with on the left hand side the filter without style="display: none;"
, and on the right hand side the filter with the property, resulting in a much stronger and smoother filter:
I am using the latest version of Opera, Firefox and Chrome on Windows, and this happens regardless of hardware acceleration being enabled or not.
Questions
Why does the absence of style="display: none;"
cause the filter to
be rendered so poorly?
Is there any workaround to render the filter correctly in Firefox, as
style="display: none;"
cannot be used with it in this context?
Thanks in advance, any help would be greatly appreciated!
Upvotes: 1
Views: 887
Reputation: 101820
In SVG, filters are supposed to be using the Linear RGB colour space by default. However it appears as if Chrome is hardwired to using the sRGB colour space when fi;ltering <video>
elements. I'm not sure why - it's possibly/probably a bug.
You can get Firefox to behave the same as Chrome, by specifying
color-interpolation-filters="sRGB"
on your filter. Unfortunately, Chrome ignores you if you try to force it to use the LinearRGB colour space (color-interpolation-filters="linearRGB"
).
And you can hide your SVG filter in the page by specifying a zero width and height on the <svg>
element.
<video autoplay controls muted src=" https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" style="width: 488px; height: 360px; filter: url(#temperature_filter)">
</video>
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
<filter id="temperature_filter" color-interpolation-filters="sRGB">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 0.694 0 0 0 0 0 0.431 0 0 0 0 0 1 0"></feColorMatrix>
</filter>
</svg>
https://jsfiddle.net/fyy5wrkw/8/
Upvotes: 3