Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gradient map filter #1046

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

YakoYakoYokuYoku
Copy link

@YakoYakoYokuYoku YakoYakoYokuYoku commented Nov 2, 2024

Add a new filter for gradient mapping.

filter_gradientmap takes a frame and maps the intensity of its color to a linear gradient denoted by a list of color and position pairs separated by semicolons. Inspired by the Color Ramp node from Blender and the Gradient Map operation from image editors such as GIMP's and Krita's.

The following is a demo of the filter.

Original.

Agent327.webm

A sepia photograph effect.

color.1='#170400 0.0' color.2='#6b4e3b 0.25' color.3='#c5a989 0.65' color.4='#dfcebf 0.85' color.5='#f6e5d5 1.0'
Agent327-sepia.webm

A thermal view effect.

color.1='#15222a 0.0' color.2='#121121 0.15' color.3='#0a46f2 0.35' color.4='#f41397 0.53' color.5='#ffa351 1.0'
Agent327-thermal.webm

@bmatherly
Copy link
Member

Some other filters already have a method for specifying color stops for a gradient. Could that method work for you? If so, it would be nice to be consistent.
Here is an example:

- identifier: color.*

@YakoYakoYokuYoku
Copy link
Author

I've tried looking into other filters but I couldn't notice how filter_lightshow does it, I thought it was in no way possible. Thanks for the tip.

@YakoYakoYokuYoku YakoYakoYokuYoku force-pushed the gradientmap branch 2 times, most recently from 291f6fb to 995a0c3 Compare November 3, 2024 17:16
@YakoYakoYokuYoku
Copy link
Author

Formatted the code with clang-format. I've preferred to use std::map instead of mlt_cache because the latter doesn't have a way to get objects by their key value. I'll add a demo to the PR comment to show what the filter can do.

@bmatherly
Copy link
Member

I had to create this patch to get this code to compile.
gradientmap.diff.txt

I've tried looking into other filters but I couldn't notice how filter_lightshow does it

Your implementation does not match the other filters because each color has two parts - the color and the position. Combining the values makes it more difficult for applications to use this API. Can you get by without the position? The other filters that use this method make the colors equally spaced - so a stop position is not required.

src/modules/plus/filter_gradientmap.cpp Outdated Show resolved Hide resolved
src/modules/plus/filter_gradientmap.cpp Outdated Show resolved Hide resolved
src/modules/plus/filter_gradientmap.cpp Show resolved Hide resolved
@bmatherly
Copy link
Member

Did you check the list of filters we get from Frei0r and avfilter to see if one of them already provide this effect?

Here is a screenshot of the UI in Shotcut for the existing gradient method. If you can switch this filter to use the same method, then the code in Shotcut would be easily reused to add a UI for it.

image

@YakoYakoYokuYoku
Copy link
Author

Your implementation does not match the other filters because each color has two parts - the color and the position. Combining the values makes it more difficult for applications to use this API.

From my point of view I don't think that combining a color and a position into a pair would be too difficult, YMMV.

Can you get by without the position? The other filters that use this method make the colors equally spaced - so a stop position is not required.

I'm afraid to tell that positioning is required for the gradient stops, if not some gradient configurations would be very difficult to replicate with equidistant stops. For instance in a gradient widget that controls its stops with slides if two slidables were too close it'd require lots of their equidistant counterparts to represent the same gradient, not even mentioning of what happens with even more sliders.

Did you check the list of filters we get from Frei0r and avfilter to see if one of them already provide this effect?

They do provide effects that involve gradients, but those are for overlays not mapping. The filter that resembles what gradient mapping does is rgblut, but that only works per RGB channel not by source intensity.

Here is a screenshot of the UI in Shotcut for the existing gradient method. If you can switch this filter to use the same method, then the code in Shotcut would be easily reused to add a UI for it.

It can reuse the same widget if it supports slidable stops, else it could be modified or subclassed to suit this need.

@bmatherly
Copy link
Member

I'm afraid to tell that positioning is required for the gradient stops, if not some gradient configurations would be very difficult to replicate with equidistant stops. For instance in a gradient widget that controls its stops with slides if two slidables were too close it'd require lots of their equidistant counterparts to represent the same gradient, not even mentioning of what happens with even more sliders.

OK. I will not require that you implement the fixed stop positions. But then lets rename this parameter so that all the color.* parameters in MLT will have the exact same interface. I suggest to rename "color." to "stop.". Someone could add the "color." parameter as an alternate to the stop parameter. Bonus points if you also implement the fixed stop method as "color." as an alternate method to specify the gradient :)

It can reuse the same widget if it supports slidable stops, else it could be modified or subclassed to suit this need.

I understand that is possible, but I think it is unlikely that a volunteer will come along to do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants