Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


Can you automatically give every subsequent letter a different color for a batch of text designs?

Community Beginner ,
Aug 18, 2021 Aug 18, 2021

Copy link to clipboard

Copied

Hi everyone, 

 

I would like to request some help with the following; I want to create a batch of text images where every single letter has a different color like in the image attached. I know how to use variables to generate multiple text designs, and I know how to manually change text color, but I was wondering if there is any way I can automatically make sure every subsequent letter (in every text image) gets a different color?

 

Many thanks!

 

 

cmxf8yerxkg71.png

TOPICS
Actions and scripting, Windows

Views

131

Likes

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

Adobe Community Professional , Aug 18, 2021 Aug 18, 2021
For text layers try this script: #target photoshop var s2t = stringIDToTypeID; (r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayersIDs')); r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum')); var lrs = executeActionGet(r).getList(p); for (var i = 0; i < lrs.count; i++) { (r = new ActionReference()).putProperty(s2t('property'), p = s2t('textKey')); r.putIdentifier(s2t('layer'), lrs.getReference(i).getIdentifier(s2t('layerID'))); if (exec...

Likes

Translate

Translate
Adobe Community Professional , Aug 21, 2021 Aug 21, 2021
If you mean first script, put on top of it: arr = [], clrs = ['004fab', '00cfb3', 'ff7000', '14a41c', 'ffd802', 'f64397', '4be715', 'ffbbb1', '8243d0', 'ff0834', 'ffd802']; Then replace: with(c.hsb) { saturation = 100, brightness = 95; do{hue = Math.random() * 360} while(Math.abs(hueDifference - hue) < 60); hueDifference = hue } to: !arr.length && arr = [].slice.call(clrs) c.rgb.hexValue = arr.shift()

Likes

Translate

Translate
Adobe Community Professional ,
Aug 18, 2021 Aug 18, 2021

Copy link to clipboard

Copied

For text layers try this script:

 

#target photoshop

var s2t = stringIDToTypeID;

(r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayersIDs'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var lrs = executeActionGet(r).getList(p);

for (var i = 0; i < lrs.count; i++) {
    (r = new ActionReference()).putProperty(s2t('property'), p = s2t('textKey'));
    r.putIdentifier(s2t('layer'), lrs.getReference(i).getIdentifier(s2t('layerID')));

    if (executeActionGet(r).hasKey(p)) {
        var textKey = executeActionGet(r).getObjectValue(p),
            style = textKey.getList(s2t('textStyleRange')).getObjectValue(0),
            text = textKey.getString(p),
            l = new ActionList(),
            hueDifference = 0;

        for (var x = 0; x < text.length; x++) {
            var k = copyDesc(style, new ActionDescriptor()),
                s = k.getObjectValue(s2t('textStyle'));

            k.putInteger(s2t('from'), x)
            k.putInteger(s2t('to'), x + 1)

            var c = new SolidColor;
            with (c.hsb) {
                saturation = 100
                brightness = 95

                do { hue = Math.random() * 360 } while (Math.abs(hueDifference - hue) < 60)
                hueDifference = hue
            }

            var d = new ActionDescriptor();
            d.putDouble(s2t('red'), c.rgb.red)
            d.putDouble(s2t('grain'), c.rgb.green)
            d.putDouble(s2t('blue'), c.rgb.blue)
            s.putObject(s2t('color'), s2t('RGBColor'), d)
            k.putObject(s2t('textStyle'), s2t('textStyle'), s)
            l.putObject(s2t('textStyleRange'), k)
        }
        if (l.count) {
            textKey.putList(s2t('textStyleRange'), l)
            var d = new ActionDescriptor();
            (r = new ActionReference()).putIdentifier(s2t('layer'), lrs.getReference(i).getIdentifier(s2t('layerID')));
            d.putReference(s2t('null'), r);
            d.putObject(s2t('to'), s2t('textLayer'), textKey);
            executeAction(s2t('set'), d, DialogModes.NO);
        }
    }

}

function copyDesc(from, to) {
    for (var i = 0; i < from.count; i++) {
        var k = from.getKey(i);
        if (to.hasKey(k)) continue;
        switch (from.getType(k)) {
            case DescValueType.ALIASTYPE: to.putPath(k, from.getPath(k)); break;
            case DescValueType.BOOLEANTYPE: to.putBoolean(k, from.getBoolean(k)); break;
            case DescValueType.CLASSTYPE: to.putClass(k, from.getClass(k)); break;
            case DescValueType.DOUBLETYPE: to.putDouble(k, from.getDouble(k)); break;
            case DescValueType.INTEGERTYPE: to.putInteger(k, from.getInteger(k)); break;
            case DescValueType.LISTTYPE: to.putList(k, from.getList(k)); break;
            case DescValueType.RAWTYPE: to.putData(k, from.getData(k)); break;
            case DescValueType.STRINGTYPE: to.putString(k, from.getString(k)); break;
            case DescValueType.LARGEINTEGERTYPE: to.putLargeInteger(k, from.getLargeInteger(k)); break;
            case DescValueType.REFERENCETYPE: to.putReference(k, from.getReference(k)); break;
            case DescValueType.OBJECTTYPE: to.putObject(k, from.getObjectType(k), from.getObjectValue(k)); break;
            case DescValueType.ENUMERATEDTYPE: to.putEnumerated(k, from.getEnumerationType(k), from.getEnumerationValue(k)); break;
            case DescValueType.UNITDOUBLE: to.putUnitDouble(k, from.getUnitDoubleType(k), from.getUnitDoubleValue(k)); break;
        }
    }
    return to
}

 

* save this code to a text file, change its extension to .jsx, place it in the presets folder (Adobe Photoshop\Presets\Scripts\). Restart Photoshop, the script will appear in the File -> Scripts menu, after that manual launch, hotkey launch, recording to the action will be available.
01.jpg02.jpg03.jpg04.jpg

This script works with styles of text layers. Randomly generated colors are used (the result is not always perfect, but each run of the script will produce a new set of color). It can work both with text typed in one layer, and with separate letters in different selected layers. 

 

For other layers (where each letter on separate layer) it will be more convenient to work with color fill using effects with this script (set random fill FX to every selected layer). Also here is example of use HSL intead HSB in script above:

 

#target photoshop

var s2t = stringIDToTypeID;

(r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayersIDs'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var lrs = executeActionGet(r).getList(p),
    hueDifference = 0;

for (var i = 0; i < lrs.count; i++) {
    (d = new ActionDescriptor()).putReference(s2t('null'), lrs.getReference(i));
    executeAction(s2t('select'), d, DialogModes.NO);

    (r = new ActionReference()).putProperty(s2t("property"), p = s2t("layerEffects"));
    r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));

    var fx = executeActionGet(r).hasKey(p) ? executeActionGet(r).getObjectValue(p) : new ActionDescriptor(),
        currentFill = fx.hasKey(p = s2t("solidFill")) ? fx.getObjectValue(p) : new ActionDescriptor();
    if (fx.hasKey(p = s2t("solidFillMulti"))) fx.erase(p);

    var saturation = 100,
        lightness = 50,
        hue = 0;

    do { hue = Math.random() * 360 } while (Math.abs(hueDifference - hue) < 60);
    hueDifference = hue

    var RGB = hslToRgb(hue, saturation, lightness)

    var d = new ActionDescriptor();
    d.putDouble(s2t('red'), RGB[0])
    d.putDouble(s2t('grain'), RGB[1])
    d.putDouble(s2t('blue'), RGB[2])
    currentFill.putObject(s2t("color"), s2t("RGBColor"), d);
    fx.putObject(s2t("solidFill"), s2t("solidFill"), currentFill);

    (d = new ActionDescriptor()).putReference(s2t("null"), r);
    d.putObject(s2t("to"), s2t("layerEffects"), fx);
    executeAction(s2t("set"), d, DialogModes.NO);
}

var r = new ActionReference();
for (var i = 0; i < lrs.count; i++) { r.putIdentifier(s2t('layer'), lrs.getReference(i).getIdentifier(s2t('layerID'))) }
(d = new ActionDescriptor()).putReference(s2t('null'), r);
executeAction(s2t('select'), d, DialogModes.NO);

function hslToRgb(h, s, l) {
    s /= 100;
    l /= 100;

    var c = (1 - Math.abs(2 * l - 1)) * s,
        x = c * (1 - Math.abs((h / 60) % 2 - 1)),
        m = l - c / 2,
        r = 0,
        g = 0,
        b = 0;

    if (0 <= h && h < 60) {
        r = c; g = x; b = 0;
    } else if (60 <= h && h < 120) {
        r = x; g = c; b = 0;
    } else if (120 <= h && h < 180) {
        r = 0; g = c; b = x;
    } else if (180 <= h && h < 240) {
        r = 0; g = x; b = c;
    } else if (240 <= h && h < 300) {
        r = x; g = 0; b = c;
    } else if (300 <= h && h < 360) {
        r = c; g = 0; b = x;
    }

    return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)]
}

 

If you can create a set of predefined colors or rules by which to determine the color difference, then the color palette can be more accurate.

Likes

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 Beginner ,
Aug 21, 2021 Aug 21, 2021

Copy link to clipboard

Copied

Hi Jazz-y, 

 

First of all, thank you so much for your reply, I was afraid I was going to have to do it all manually! To follow up, suppose I have a list of colors that I would like to use in a certain order, how would I have to change the script? For example; 

 

004fab

00cfb3

ff7000

14a41c

ffd802

f64397

4be715

ffbbb1

8243d0

ff0834

ffd802

 

And then after the last one start over again with the first color?

 

Thanks again!

 

Kind regards,

Likes

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
Adobe Community Professional ,
Aug 21, 2021 Aug 21, 2021

Copy link to clipboard

Copied

If you mean first script, put on top of it:

 

arr = [], clrs = ['004fab', '00cfb3', 'ff7000', '14a41c', 'ffd802',
'f64397', '4be715', 'ffbbb1', '8243d0', 'ff0834', 'ffd802'];

 

Then replace:

 

with(c.hsb) {
	saturation = 100, brightness = 95; do{hue = Math.random() * 360}
	while(Math.abs(hueDifference - hue) < 60); hueDifference = hue
}

 

to:

 

!arr.length &&
arr = [].slice.call(clrs)
c.rgb.hexValue = arr.shift()

 

Likes

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 Beginner ,
Sep 13, 2021 Sep 13, 2021

Copy link to clipboard

Copied

Hi Kukurykus, 

 

Thank you, I got it all to work. I did notice however that the colors are still randomized once I run the script, so I have to run it a couple times if I don't like the order. Do you know how I can make sure the colors only follow a certain order? For example; first color 004fab, second color 00cfb3, third color ff7000, etcetera. 

 

Many thanks!

 

Kind regards

 

Likes

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
Adobe Community Professional ,
Sep 13, 2021 Sep 13, 2021

Copy link to clipboard

Copied

I tested my update to the given code and it works as requested, without randomization.

Likes

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 Beginner ,
Sep 13, 2021 Sep 13, 2021

Copy link to clipboard

Copied

LATEST

I tried it again and it worked indeed. Must've done something wrong the first time. 

 

Thanks again!

 

 

Likes

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