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

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

2.3K

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

Guide , 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
...

Votes

Translate

Translate
LEGEND , 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()

 

Votes

Translate

Translate
Adobe
Guide ,
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.

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 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,

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
LEGEND ,
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()

 

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 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

 

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
LEGEND ,
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.

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

Copy link to clipboard

Copied

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

 

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
New Here ,
Dec 09, 2023 Dec 09, 2023

Copy link to clipboard

Copied

Hey can you give me please the correct Script ? cause it dident work for me !! 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
New Here ,
Mar 27, 2024 Mar 27, 2024

Copy link to clipboard

Copied

LATEST

Hi there,

Is there any way to apply each pattern like image (layer or smart object) for each letter in the whole layer text?
Example: I have 10 different images or patterns and I have a layer text that has 10 letters, so how can I apply each pattern/image for each letter in a certain order and when the last pattern/image in the list was applied then they will start over again with the first pattern/image.
Hope for any comment to help!

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