• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Gradient from background and foreground can't be automated?

Explorer ,
Apr 28, 2024 Apr 28, 2024

Copy link to clipboard

Copied

Hi, it's me again, thanks for the help on my last post.
I've been working on this text layers that need a gradient overlay based on some colors, so what I'm doing is picking color 1 as background and color 2 as foreground, and when I add a gradient overlay, theres a preset that let's me use the background/foreground colors as gradient, so I wanted to automate that, I recorded the action and it does pretty much it, however, is not using my current background/foreground colors, but the ones from the time i recorded the action, and I was wondering if there's a way to automate that? So I can pick two colors and run an action/script that adds them as a gradient overlay, I don´t care about the angle or style, the basic 90 degree linear gradient works.
I found some scripts about gradients, but not about text overlay.

Iuigidesu_1-1714326909221.png

Here's a little representation of what I'm doing manually.
Thanks!!

TOPICS
Actions and scripting

Views

204

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 2 Correct answers

Community Expert , Apr 28, 2024 Apr 28, 2024

Yes, sadly actions often record absolute final values, even if we try to use a "foreground to background" gradient preset.

 

You can substitute the action step for an "action helper script":

 

/*
Gradient Overlay Using Foreground to Background.jsx
v1.0 - 29th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/gradient-from-background-and-foreground-can-t-be-automated/td-p/14585544
*/

#target photoshop

var c2t = function (s) {
	return app.charIDToTypeID(s);
...

Votes

Translate

Translate
Community Expert , May 01, 2024 May 01, 2024

@Iuigidesu 

 

Try this:

 

/*
Stroke & Gradient Overlay Using Foreground to Background.jsx
v1.0 - 2nd May 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/gradient-from-background-and-foreground-can-t-be-automated/td-p/14585544
*/

var s2t = function (s) {
	return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var descriptor3 = new ActionDescriptor();
var descriptor4 = new ActionDescriptor();
var des
...

Votes

Translate

Translate
Adobe
Community Expert ,
Apr 28, 2024 Apr 28, 2024

Copy link to clipboard

Copied

Yes, sadly actions often record absolute final values, even if we try to use a "foreground to background" gradient preset.

 

You can substitute the action step for an "action helper script":

 

/*
Gradient Overlay Using Foreground to Background.jsx
v1.0 - 29th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/gradient-from-background-and-foreground-can-t-be-automated/td-p/14585544
*/

#target photoshop

var c2t = function (s) {
	return app.charIDToTypeID(s);
};
var s2t = function (s) {
	return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var descriptor3 = new ActionDescriptor();
var descriptor4 = new ActionDescriptor();
var descriptor5 = new ActionDescriptor();
var descriptor6 = new ActionDescriptor();
var descriptor7 = new ActionDescriptor();
var descriptor8 = new ActionDescriptor();
var descriptor9 = new ActionDescriptor();
var descriptor10 = new ActionDescriptor();
var descriptor11 = new ActionDescriptor();
var list = new ActionList();
var list2 = new ActionList();
var reference = new ActionReference();
reference.putProperty( s2t( "property" ), s2t( "layerEffects" ));
reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
descriptor2.putUnitDouble( s2t( "scale" ), s2t( "percentUnit" ), 100.000000 );
descriptor3.putBoolean( s2t( "enabled" ), true );
descriptor3.putBoolean( s2t( "present" ), true );
descriptor3.putBoolean( s2t( "showInDialog" ), true );
descriptor3.putEnumerated( s2t( "mode" ), s2t( "blendMode" ), s2t( "normal" ));
descriptor3.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), 100.000000 );
descriptor4.putString( s2t( "name" ), "Foreground to Background" );
descriptor4.putEnumerated( s2t( "gradientForm" ), s2t( "gradientForm" ), s2t( "customStops" ));
descriptor4.putDouble(s2t("interfaceIconFrameDimmed"), 4096.000000);
// Foreground colour
var fR = foregroundColor.rgb.red;
var fG = foregroundColor.rgb.green;
var fB = foregroundColor.rgb.blue
descriptor6.putDouble( s2t( "red" ), Math.round(fR) );
descriptor6.putDouble( s2t( "grain" ), Math.round(fG) );
descriptor6.putDouble( s2t( "blue" ), Math.round(fB) );
descriptor5.putObject(s2t("color"), s2t("RGBColor"), descriptor6);
descriptor5.putEnumerated( s2t( "type" ), s2t( "colorStopType" ), s2t( "userStop" ));
descriptor5.putInteger( s2t( "location" ), 0 );
descriptor5.putInteger( s2t( "midpoint" ), 50 );
list.putObject(s2t("colorStop"), descriptor5);
// Background colour
var bR = backgroundColor.rgb.red;
var bG = backgroundColor.rgb.green;
var bB = backgroundColor.rgb.blue
descriptor8.putDouble( s2t( "red" ), Math.round(bR) );
descriptor8.putDouble( s2t( "grain" ), Math.round(bG) );
descriptor8.putDouble( s2t( "blue" ), Math.round(bB) );
descriptor7.putObject(s2t("color"), s2t("RGBColor"), descriptor8);
descriptor7.putEnumerated( s2t( "type" ), s2t( "colorStopType" ), s2t( "userStop" ));
descriptor7.putInteger( s2t( "location" ), 4096 );
descriptor7.putInteger( s2t( "midpoint" ), 50 );
list.putObject( s2t( "colorStop" ), descriptor7 );
descriptor4.putList( s2t( "colors" ), list );
descriptor9.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), 100.000000 );
descriptor9.putInteger( s2t( "location" ), 0 );
descriptor9.putInteger( s2t( "midpoint" ), 50 );
list2.putObject( s2t( "transferSpec" ), descriptor9 );
descriptor10.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), 100.000000 );
descriptor10.putInteger( s2t( "location" ), 4096 );
descriptor10.putInteger( s2t( "midpoint" ), 50 );
list2.putObject( s2t( "transferSpec" ), descriptor10 );
descriptor4.putList( s2t( "transparency" ), list2 );
descriptor3.putObject(s2t("gradient"), s2t("gradientClassEvent"), descriptor4);
// Gradient angle
descriptor3.putUnitDouble( s2t( "angle" ), s2t( "angleUnit" ), 90.000000 );
descriptor3.putEnumerated(s2t("type"), s2t("gradientType"), s2t("linear"));
// Boolean to reverse the gradient direction
descriptor3.putBoolean( s2t( "reverse" ), true );
descriptor3.putBoolean( s2t( "dither" ), false );
descriptor3.putEnumerated( c2t( "gs99" ), s2t( "gradientInterpolationMethodType" ), s2t( "perceptual" ));
descriptor3.putBoolean( s2t( "align" ), true );
descriptor3.putUnitDouble( s2t( "scale" ), s2t( "percentUnit" ), 100.000000 );
descriptor11.putUnitDouble( s2t( "horizontal" ), s2t( "percentUnit" ), 0.000000 );
descriptor11.putUnitDouble( s2t( "vertical" ), s2t( "percentUnit" ), 0.000000 );
descriptor3.putObject( s2t( "offset" ), s2t( "paint" ), descriptor11 );
descriptor2.putObject( s2t( "gradientFill" ), s2t( "gradientFill" ), descriptor3 );
descriptor.putObject( s2t( "to" ), s2t( "layerEffects" ), descriptor2 );
executeAction( s2t( "set" ), descriptor, DialogModes.NO );

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 30, 2024 Apr 30, 2024

Copy link to clipboard

Copied

@Iuigidesu 

 

How did the script work for you?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 30, 2024 Apr 30, 2024

Copy link to clipboard

Copied

Hey, thanks, it's super cool and also super fast, however it cleans all the original effects, and all the layers I work on must keep their original stroke, but I use an action to put it again, other than that, works amazing, thanks again!!!!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 30, 2024 Apr 30, 2024

Copy link to clipboard

Copied

Yes, it wasn't clear to me that you had existing effects (looking at your screenshot I can see that now). The expectation is that this is a brand new effect.

 

Due to the way that Adobe programmed effects, it is very difficult to modify existing effects unless one is very advanced in AM code scripting.

 

EDIT: The other option would be to post a layered sample file with the required effects applied, then I could modify the gradient code while retaining the existing effects.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 30, 2024 Apr 30, 2024

Copy link to clipboard

Copied

Since all the text layers I'm working on have the same stroke size, I just made an action that runs the gradient script and adds a 5px stroke, so nothing to worry about, thanks!!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 01, 2024 May 01, 2024

Copy link to clipboard

Copied

Sorry, @Stephen_A_Marsh , I thought I figured the stroke thing, but now i started actually working on it, turns out you can't even add a stroke as an action, it'll record all the other effects, so now I got to add manually the stroke, which isn't really helpful, so I was wondering how to make the script to add a stroke? The layers I'm working on use the exact same stroke size (6px) and black or white color, I'd love some help on this, you told me last time to send a sample, so I'll add it. Thanks!!!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
May 01, 2024 May 01, 2024

Copy link to clipboard

Copied

You can add an effect to existing ones using the set_fx() function. You need to create a descriptor with the parameters of the desired effect and call the function.
The example shows how you can add a stroke effect without worrying about what effects were (or were not) applied to the layer before.

 

// cteate stroke fx descriptor
var d = new ActionDescriptor();
d.putBoolean(stringIDToTypeID("enabled"), true);
d.putEnumerated(stringIDToTypeID("style"), stringIDToTypeID("frameStyle"), stringIDToTypeID("outsetFrame"));
d.putEnumerated(stringIDToTypeID("paintType"), stringIDToTypeID("frameFill"), stringIDToTypeID("solidColor"));
d.putEnumerated(stringIDToTypeID("mode"), stringIDToTypeID("blendMode"), stringIDToTypeID("normal"));
d.putUnitDouble(stringIDToTypeID("opacity"), stringIDToTypeID("percentUnit"), 100);
d.putUnitDouble(stringIDToTypeID("size"), stringIDToTypeID("pixelsUnit"), 18);
var d1 = new ActionDescriptor();
d1.putDouble(stringIDToTypeID("red"),   255);
d1.putDouble(stringIDToTypeID("green"), 0);
d1.putDouble(stringIDToTypeID("blue"),  0);
d.putObject(stringIDToTypeID("color"), stringIDToTypeID("RGBColor"), d1);

set_fx("frameFX", d);

function set_fx(fx_type, fx_desc)
    {
    try {
        var fx = new ActionDescriptor();

        var r = new ActionReference();
        r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("layerEffects"));
        r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));

        var d = executeActionGet(r);
        if (d.hasKey(stringIDToTypeID("layerEffects"))) fx = d.getObjectValue(stringIDToTypeID("layerEffects"));

        var d = new ActionDescriptor();
        var r = new ActionReference();
        r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("layerEffects"));
        r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
        d.putReference(stringIDToTypeID("null"), r);

        fx.putObject(stringIDToTypeID(fx_type), stringIDToTypeID(fx_type), fx_desc);

        d.putObject(stringIDToTypeID("to"), stringIDToTypeID("layerEffects"), fx);
        executeAction(stringIDToTypeID("set"), d, DialogModes.NO);
        }
    catch (e) { alert(e.line+"\n\n"+e); }
    }

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 01, 2024 May 01, 2024

Copy link to clipboard

Copied

@Iuigidesu 

 

Try this:

 

/*
Stroke & Gradient Overlay Using Foreground to Background.jsx
v1.0 - 2nd May 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/gradient-from-background-and-foreground-can-t-be-automated/td-p/14585544
*/

var s2t = function (s) {
	return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var descriptor3 = new ActionDescriptor();
var descriptor4 = new ActionDescriptor();
var descriptor5 = new ActionDescriptor();
var descriptor6 = new ActionDescriptor();
var descriptor7 = new ActionDescriptor();
var descriptor8 = new ActionDescriptor();
var descriptor9 = new ActionDescriptor();
var descriptor10 = new ActionDescriptor();
var descriptor11 = new ActionDescriptor();
var descriptor12 = new ActionDescriptor();
var descriptor13 = new ActionDescriptor();
var list = new ActionList();
var list2 = new ActionList();
var reference = new ActionReference();
reference.putProperty( s2t( "property" ), s2t( "layerEffects" ));
reference.putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "targetEnum" ));
descriptor.putReference( s2t( "null" ), reference );
descriptor2.putUnitDouble( s2t( "scale" ), s2t( "percentUnit" ), 100.000000 );
descriptor3.putBoolean( s2t( "enabled" ), true );
descriptor3.putBoolean( s2t( "present" ), true );
descriptor3.putBoolean( s2t( "showInDialog" ), true );
descriptor3.putEnumerated( s2t( "mode" ), s2t( "blendMode" ), s2t( "normal" ));
descriptor3.putUnitDouble(s2t("opacity"), s2t("percentUnit"), 100.000000);
///// Gradient settings /////
descriptor4.putString( s2t( "name" ), "Foreground to Background" );
descriptor4.putEnumerated( s2t( "gradientForm" ), s2t( "gradientForm" ), s2t( "customStops" ));
descriptor4.putDouble(s2t("interfaceIconFrameDimmed"), 4096.000000);
// Foreground colour
var fR = foregroundColor.rgb.red;
var fG = foregroundColor.rgb.green;
var fB = foregroundColor.rgb.blue
descriptor6.putDouble( s2t( "red" ), Math.round(fR) );
descriptor6.putDouble( s2t( "grain" ), Math.round(fG) );
descriptor6.putDouble( s2t( "blue" ), Math.round(fB) );
descriptor5.putObject( s2t( "color" ), s2t( "RGBColor" ), descriptor6 );
descriptor5.putEnumerated( s2t( "type" ), s2t( "colorStopType" ), s2t( "userStop" ));
descriptor5.putInteger( s2t( "location" ), 0 );
descriptor5.putInteger( s2t( "midpoint" ), 50 );
list.putObject(s2t("colorStop"), descriptor5);
// Background colour
var bR = backgroundColor.rgb.red;
var bG = backgroundColor.rgb.green;
var bB = backgroundColor.rgb.blue
descriptor8.putDouble( s2t( "red" ), Math.round(bR) );
descriptor8.putDouble( s2t( "grain" ), Math.round(bG) );
descriptor8.putDouble( s2t( "blue" ), Math.round(bB) );
descriptor7.putObject( s2t( "color" ), s2t( "RGBColor" ), descriptor8 );
descriptor7.putEnumerated( s2t( "type" ), s2t( "colorStopType" ), s2t( "userStop" ));
descriptor7.putInteger( s2t( "location" ), 4096 );
descriptor7.putInteger( s2t( "midpoint" ), 50 );
list.putObject( s2t( "colorStop" ), descriptor7 );
descriptor4.putList( s2t( "colors" ), list );
descriptor9.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), 100.000000 );
descriptor9.putInteger( s2t( "location" ), 0 );
descriptor9.putInteger( s2t( "midpoint" ), 50 );
list2.putObject( s2t( "transferSpec" ), descriptor9 );
descriptor10.putUnitDouble( s2t( "opacity" ), s2t( "percentUnit" ), 100.000000 );
descriptor10.putInteger( s2t( "location" ), 4096 );
descriptor10.putInteger( s2t( "midpoint" ), 50 );
list2.putObject( s2t( "transferSpec" ), descriptor10 );
descriptor4.putList( s2t( "transparency" ), list2 );
descriptor3.putObject(s2t("gradient"), s2t("gradientClassEvent"), descriptor4);
// Gradient angle
descriptor3.putUnitDouble( s2t( "angle" ), s2t( "angleUnit" ), 65.000000 );
descriptor3.putEnumerated(s2t("type"), s2t("gradientType"), s2t("linear"));
// Boolean to reverse the gradient direction
descriptor3.putBoolean( s2t( "reverse" ), true );
descriptor3.putBoolean( s2t( "dither" ), false );
descriptor3.putBoolean( s2t( "align" ), true );
descriptor3.putUnitDouble( s2t( "scale" ), s2t( "percentUnit" ), 100.000000 );
descriptor11.putUnitDouble( s2t( "horizontal" ), s2t( "percentUnit" ), 0.000000 );
descriptor11.putUnitDouble( s2t( "vertical" ), s2t( "percentUnit" ), 0.000000 );
descriptor3.putObject( s2t( "offset" ), s2t( "paint" ), descriptor11 );
descriptor2.putObject(s2t("gradientFill"), s2t("gradientFill"), descriptor3);
///// Stroke settings /////
descriptor12.putBoolean( s2t( "enabled" ), true );
descriptor12.putBoolean( s2t( "present" ), true );
descriptor12.putBoolean( s2t( "showInDialog" ), true );
descriptor12.putEnumerated( s2t( "style" ), s2t( "frameStyle" ), s2t( "outsetFrame" ));
descriptor12.putEnumerated( s2t( "paintType" ), s2t( "frameFill" ), s2t( "solidColor" ));
descriptor12.putEnumerated( s2t( "mode" ), s2t( "blendMode" ), s2t( "normal" ));
descriptor12.putUnitDouble(s2t("opacity"), s2t("percentUnit"), 100.000000);
// Stroke thickness
descriptor12.putUnitDouble(s2t("size"), s2t("pixelsUnit"), 5.000000); 
// Stroke red value
descriptor13.putDouble( s2t( "red" ), 0 );
// Stroke green value
descriptor13.putDouble( s2t( "grain" ), 0 );
// Stroke blue value
descriptor13.putDouble( s2t( "blue" ), 0 );
descriptor12.putObject( s2t( "color" ), s2t( "RGBColor" ), descriptor13 );
descriptor12.putBoolean( s2t( "overprint" ), false );
descriptor2.putObject( s2t( "frameFX" ), s2t( "frameFX" ), descriptor12 );
descriptor.putObject( s2t( "to" ), s2t( "layerEffects" ), descriptor2 );
executeAction( s2t( "set" ), descriptor, DialogModes.NO );

 

This adds a black stroke.

 

You can either manually change the style to use white after it is applied, or create a second version of the above but change 0 to 255:

 

// Stroke red value
descriptor13.putDouble( s2t( "red" ), 255 );

 

Repeating for the blue and green values entries.  

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 01, 2024 May 01, 2024

Copy link to clipboard

Copied

LATEST

THANK YOU!!!!!!!
This will save me so much time, It does exactly all I need, thanks!!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines