Jan 24, 2021 Jan 24, 2021

Copied

Hello dear scripting professionals.

Given the case that a shape is filled with a gradient and this gradient is composed of known standardized swatch colors (and only those swatch colors, 100% opacity), what is the way to use gradient stop rampPoints, midPoints, anything else, to determine the most dominant color by how much this color spreads across the gradient and takes up the most spectrum.

Thanks to anyone taking a look!

TOPICS
Scripting

Views

160

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
5 Replies 5
Jan 24, 2021 Jan 24, 2021

Copied

midPoint is the place where the colors are equal (50% of each one). Gradient points are places where the one color value is 100% and the other's is 0%. So, using Location field, tou can determine the spreading of the color and its changing speed.

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Enthusiast ,
Jan 24, 2021 Jan 24, 2021

Copied

I think a formula to quantify dominance would be:

(distance between stop and stop before) * (fraction of mid point on that side) +

(distance between stop and stop after) * (fraction of mid point on that side)

So if you have four colors

``````var stops = selection[0].fillColor.gradient.gradientStops;

var d0 = stops[0].rampPoint;
var d1 = stops[1].rampPoint-stops[0].rampPoint;
var d2 = stops[2].rampPoint-stops[1].rampPoint;
var d3 = stops[3].rampPoint-stops[2].rampPoint;
var d4 = 100-stops[3].rampPoint;

var colors = [
{
value: d0 + (d1 * (stops[0].midPoint / 100)),
name: "magenta"
},
{
value: (d1 * ((100-stops[0].midPoint) / 100)) + (d2 * (stops[1].midPoint / 100)),
name: "yellow"
},
{
value: (d2 * ((100-stops[1].midPoint) / 100)) + (d3 * (stops[2].midPoint / 100)),
name: "cyan"
},
{
value: (d3 * ((100-stops[2].midPoint) / 100)) + d4,
name: "black"
}
];

// most dominant to least dominant
colors.sort(function(a, b) {return b.value - a.value;})

alert( colors[0].name + " - " + colors[0].value + "\
" + colors[1].name + " - " + colors[1].value + "\
" + colors[2].name + " - " + colors[2].value + "\
" + colors[3].name + " - " + colors[3].value );``````

This doesn't take into account repeated colors.

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Engaged ,
Jan 24, 2021 Jan 24, 2021

Copied

My thoughts are exactly as @femkeblanco. I wonder if we are being naive? I can imagine cases where a human looking at the gradient would pick the eye-popping color from the 'dominant' color. Anyway, for fun, I've had a go at an implementation:

``````// select an item with gradent fillColor before running script
var item = selection[0];

var dominantColor = colorStats[0];
\$.writeln(dominantColor.name + ': ' + dominantColor.score + ' percent coverage');

var colrs = {}, currentRampPoint = 0, currentStop, currentColorName, prevColorName, currentRampPoint, prevRampPoint, currentMidPoint, prevMidPoint;

if (colrs[currentColorName] == undefined) {
// add new color to keep track of
colrs[currentColorName] = { score: 0 };
}

if (i > 0) {
// work out strength of color based on length of stop and midpoint (assumes linear function!)
colrs[prevColorName].score += (currentRampPoint - prevRampPoint) * (prevMidPoint / 100)
colrs[currentColorName].score += (currentRampPoint - prevRampPoint) * ((100 - prevMidPoint) / 100)
}

prevRampPoint = currentRampPoint;
prevColorName = currentColorName;
prevMidPoint = currentMidPoint;
}

// return a sorted array
sortedColrs = [];
for (var colr in colrs) {
sortedColrs.push({ name: colr, score: colrs[colr].score });
}
sortedColrs.sort(function (a, b) { return b.score - a.score });

return sortedColrs;
}``````

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Jan 24, 2021 Jan 24, 2021

Copied

These are great explorations and potential solutions, or otherwise useful exercises for gradient nees.

However, I must come clean and disclose that this question was driven by another goal, which is to create a process to turn color-to-color gradients into color-to-transparency gradients by applying an opacity mask in the shape of the inverted gradient on top of a shape of flat color. The simplest case is a gradient which has the spot color going to the same color, but it's transparent. The more complex case is multiple spot colors going from one to another, which results in layers of masked shapes (each new mask gets the same gradient, but the stops are changed to all black and opacity 0 is set for stops which are not the current name-group (the spot name)).

During this, I found that although the resulting layered masked shapes make a visual result that is comparable and acceptable within tolerance, putting a background behind this set of shapes shows that it will indeed show through thin transparency areas which occur between color stops fading into each other.
Therefore it would be necessary to place a flat-color background behind the entire set so that this color will fill in any thinly transparent gradated areas.
It was my thought that the color which recurs the most in a gradient should be that final background color. However, I noticed that while there can be many stops of a color, the midpoints and such can make those colors actually less prominent despite the amounts of stops containing those colors. i.e. they could occupy less space.
So, I went here to ask this question but continued my work meanwhile.
And in my work, I also observed that actually, none of this is quite correct given the workflow at hand.

What ends up happening is that the resulting masked gradated shapes create a layered structure which compounds to create such blending that the most-stop approach seems to work Ok. In this image, the top-right shape was automatically assigned the Yellow color as the background. The one below has what I would think should be the best color, Green. Visually it has tighter lines, because in the context of being layered thus, there is a color that is out order concerning the new blending interactions which are created. You can see that in the area of red-yellow gradation that there is a greenish hue showing a little bit and making the area somewhat uglier and not as close to the original shape than the yellow color.

As I said, for the needs at this time, this appears satisfactory. Using the answers here it may be possible to better refine the 'most stops' approach to create an even better layering arrangement. Yet, as what I've got appears to be workable already, I'm not sure I will pursue further refinement until such time that new needs would call for it.

Thank you all for great insight, it will surely help everyone and probably me later.

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Engaged ,
Jan 24, 2021 Jan 24, 2021

Copied

LATEST

Hi @Silly-V, that's an interesting problem. I don't think it has a general answer though. I think there will be spot color combos that can never be good, but I might be wrong. Anyway, it was fun to play with and useful for my learning. 🙂

- Mark

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Resources
Learning Resources for Illustrator
What's new and fixed in Illustrator
Fonts and Typography in Illustrator