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

Is it possible to automate filling multiple selections with random colors?

Community Beginner ,
Aug 26, 2021 Aug 26, 2021

Copy link to clipboard

Copied

Let's say I've got 1000 discreet squares in my .psd file. Would it be possible to fill them all with random colors? Preferably with no duplicates?

 

The actual final file will have probably somewhere between ~2000 and ~5000 shapes (not all of them regular), which should all filled with a flat, distinct RGB color. It could be done by hand... but I'd much prefer to automate this task, if possible.

 

Thanks in advance for reading and assistance!

TOPICS
Actions and scripting , Windows

Views

596

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
Guide ,
Aug 26, 2021 Aug 26, 2021

Copy link to clipboard

Copied

what are squares? this selection, mask, pixels in one layer, pixels in different layers,  closed paths in one layer, vector shapes in different layers, etc.

 

it would be ideal if you could upload a test file that would make your task clear

 

P.s. set random color to all selected layers using fill FX

2021-08-27_09-10-27.png2021-08-27_09-10-48.png

 

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 27, 2021 Aug 27, 2021

Copy link to clipboard

Copied

Thanks for your answer, this is about the gist of it. Specifically, I should have said multiple, seperate active selections (as in several disconnected selected areas on the same layer).

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 ,
Aug 27, 2021 Aug 27, 2021

Copy link to clipboard

Copied

So how is this selection made? Can you post an example? From what you describe, it might be possible to create a alpha mask of the selection, then go through that and detect each separate selection, and apply a random color, but that would still take a long time, even with a script. 

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
Guide ,
Aug 28, 2021 Aug 28, 2021

Copy link to clipboard

Copied

As I understand it, the selection is created on the basis of a pixel layer (that is, it is a set of some objects separated by transparency or color).

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 ,
Aug 27, 2021 Aug 27, 2021

Copy link to clipboard

Copied

Shape layer are fill layers with vector layer mask.  To have 5000 different solid color discreet shapes you would be dealing withe 5000 layers.   A pattern could have 5000 colors so you could flatten your 5000 shape layer define a define the is the merge if 5000 colored shapes. however if there was overlap between layers some shapes will be altered,  wiped, out or even blender into more than 5000 colors and shapes.

 

An active selection can have 5000  separate areas but it can not bet filled with 5000 colors.  5000 different selection can be filled with 5000 colors like as swatch color panel.

JJMack

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
Guide ,
Aug 27, 2021 Aug 27, 2021

Copy link to clipboard

Copied

There is one problem with shape layers - they need to be selected before changing the color (at least I couldn't do it any other way).I made a test document with 3200 layers. This code changes the color of the selected layers at a rate of about 3 layers per second. It's very slow 😞

 

#target photoshop

var s2t = stringIDToTypeID;

doProgress("", "main()")

function main() {

    (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++) {
        app.updateProgress(i + 1, lrs.count);
        app.changeProgressText(i);

        (r = new ActionReference()).putIdentifier(s2t('layer'), lrs.getReference(i).getIdentifier(s2t('layerID')));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        executeAction(s2t('select'), d, DialogModes.NO);
        (r = new ActionReference()).putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
        (d = new ActionDescriptor()).putReference(s2t("null"), r);
        (d1 = new ActionDescriptor()).putDouble(s2t('red'), Math.random() * 255);
        d1.putDouble(s2t('grain'), Math.random() * 255);
        d1.putDouble(s2t('blue'), Math.random() * 255);
        (d2 = new ActionDescriptor()).putObject(s2t("color"), s2t("RGBColor"), d1);
        (d3 = new ActionDescriptor()).putObject(s2t("fillContents"), s2t("solidColorLayer"), d2);
        d.putObject(s2t("to"), s2t("shapeStyle"), d3);
        executeAction(s2t("set"), d, DialogModes.NO);
    }
}

2021-08-27_16-36-39.png

 

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 ,
Aug 27, 2021 Aug 27, 2021

Copy link to clipboard

Copied

Yea, that many layers is going to really slow down PS. I do a lot of scripting creating gradients to layers and creating new layers. I end up doing it in pieces now and flattening a portion of it, just so I'm not sitting there all day.

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 27, 2021 Aug 27, 2021

Copy link to clipboard

Copied

Thanks for clearing things up, and yes I was referring to active selection--which is a shame, but understable. Thank 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
Guide ,
Aug 28, 2021 Aug 28, 2021

Copy link to clipboard

Copied

LATEST

Try it. The fill is based on a selection. I added control over the repeatability of colors (they may be close, but not the same). It took about 25 minutes to fill 4000 selected objects

 

#target photoshop

activeDocument.suspendHistory('fill selection', 'main()')

function main() {
    var doc = new AM('document'),
        lr = new AM('layer'),
        pth = new AM('path'),
        channel = new AM('channel'),
        presentColors = {};

    doProgress("", "fillSelection()")

    function fillSelection() {
        if (doc.hasProperty('selection')) {
            lr.makeChannelFromSelection('selection')
            lr.makePathFromSelection(1);
            lr.select(lr.newLayer('colors'))
            var pathContents = pth.getProperty('pathContents').value.getList(stringIDToTypeID('pathComponents'))

            try {
                channel.delete('current fill')
                channel.makeSelection('selection')
            } catch (e) { }

            for (var i = 0; i < pathContents.count; i++) {
                updateProgress(i + 1, pathContents.count);
                changeProgressText(i);
                pth.makePathFromSubpath(pathContents.getObjectValue(i))
                pth.makeSelectionFromPath()
                lr.expandSelection(1)
                lr.makeChannelFromSelection('current fill')
                channel.select('current fill')
                doc.deselect()
                channel.invert()
                channel.makeSelection('selection')
                channel.subtractFromSelection('current fill')
                channel.delete('current fill')
                lr.fillByRandomColor(presentColors)
            }
            lr.deselect()
            channel.delete('selection')
            pth.delete()
        }
    }
}

function AM(target, order) {
    var s2t = stringIDToTypeID,
        t2s = typeIDToStringID;

    target = target ? s2t(target) : null;

    this.getProperty = function (property, id, idxMode) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id != undefined ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id)) :
            r.putEnumerated(target, s2t('ordinal'), order ? s2t(order) : s2t('targetEnum'));
        return getDescValue(executeActionGet(r), property)
    }

    this.hasProperty = function (property, id, idxMode) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id))
            : r.putEnumerated(target, s2t('ordinal'), order ? s2t(order) : s2t('targetEnum'));
        return executeActionGet(r).hasKey(property)
    }

    this.select = function (id) {
        var r = new ActionReference();
        if (typeof id == 'number') r.putIdentifier(target, id) else r.putName(target, id);
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        executeAction(s2t('select'), d, DialogModes.NO);
    }

    this.makeSelectionFromPath = function () {
        (r = new ActionReference()).putProperty(s2t('channel'), s2t('selection'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        (r1 = new ActionReference()).putProperty(s2t('path'), s2t('workPath'));
        d.putReference(s2t('to'), r1);
        d.putBoolean(s2t('vectorMaskParams'), true);
        executeAction(s2t('set'), d, DialogModes.NO);
    }

    this.deleteCurrentPath = function () {
        (r = new ActionReference()).putProperty(s2t('path'), s2t('workPath'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        executeAction(s2t('delete'), d, DialogModes.NO);
    }

    this.makePathFromSelection = function (tolerance) {
        tolerance = tolerance ? tolerance : 10;
        (r = new ActionReference()).putClass(s2t('path'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        (r1 = new ActionReference()).putProperty(s2t('selectionClass'), s2t('selection'));
        d.putReference(s2t('from'), r1);
        d.putUnitDouble(s2t('tolerance'), s2t('pixelsUnit'), tolerance);
        executeAction(s2t('make'), d, DialogModes.NO);
    }

    this.makePathFromSubpath = function (pth) {
        (r = new ActionReference()).putProperty(stringIDToTypeID("path"), stringIDToTypeID("workPath"));
        (d = new ActionDescriptor()).putReference(stringIDToTypeID("null"), r);
        (l = new ActionList()).putObject(stringIDToTypeID("pathComponent"), pth);
        d.putList(stringIDToTypeID("to"), l);
        executeAction(stringIDToTypeID("set"), d, DialogModes.NO);
    }

    this.newLayer = function (name) {
        (d1 = new ActionDescriptor()).putString(s2t('name'), name);
        (d = new ActionDescriptor()).putObject(s2t('new'), s2t('layer'), d1);
        return (executeAction(s2t('make'), d, DialogModes.NO)).getInteger(s2t('layerID'))
    }

    this.makeChannelFromSelection = function (name) {
        (d = new ActionDescriptor()).putString(s2t("name"), name);
        d.putEnumerated(s2t("colorIndicates"), s2t("maskIndicator"), s2t("selectedAreas"));
        (d1 = new ActionDescriptor()).putObject(s2t("new"), s2t("channel"), d);
        (r = new ActionReference()).putProperty(s2t("channel"), s2t("selection"));
        d1.putReference(s2t("using"), r);
        executeAction(s2t("make"), d1, DialogModes.NO);
    }

    this.deselect = function () {
        (r = new ActionReference()).putProperty(s2t('channel'), s2t('selection'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        d.putEnumerated(s2t('to'), s2t('ordinal'), s2t('none'));
        executeAction(s2t('set'), d, DialogModes.NO);
    }

    this.invert = function () {
        executeAction(s2t("invert"), undefined, DialogModes.NO);
    }

    this.makeSelection = function (name) {
        (r = new ActionReference()).putProperty(target, s2t('selection'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        (r1 = new ActionReference()).putName(target, name);
        d.putReference(s2t('to'), r1);
        executeAction(s2t('set'), d, DialogModes.NO);
    }

    this.subtractFromSelection = function (name) {
        (r = new ActionReference()).putName(target, name);
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        (r1 = new ActionReference()).putProperty(target, s2t('selection'));
        d.putReference(s2t('from'), r1);
        executeAction(s2t('subtract'), d, DialogModes.NO);

    }

    this.expandSelection = function (px) {
        (d = new ActionDescriptor()).putUnitDouble(s2t('by'), s2t('pixelsUnit'), px);
        executeAction(s2t('expand'), d, DialogModes.NO);
    }

    this.delete = function (name) {
        var r = new ActionReference();
        if (name) r.putName(target, name) else r.putEnumerated(target, s2t('ordinal'), s2t('targetEnum'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        executeAction(s2t('delete'), d, DialogModes.NO);
    }

    this.fillByRandomColor = function (colorObj) {
        var c = new SolidColor;
        with (c.rgb) {
            do {
                red = Math.random() * 255
                green = Math.random() * 255
                blue = Math.random() * 255
            } while (colorObj[hexValue])

            colorObj[hexValue] = true;

            (d = new ActionDescriptor()).putEnumerated(s2t("using"), s2t("fillContents"), s2t("color"));
            (d1 = new ActionDescriptor()).putDouble(s2t("red"), red);
            d1.putDouble(s2t("green"), green);
            d1.putDouble(s2t("blue"), blue);
            d.putObject(s2t("color"), s2t("RGBColor"), d1);
            executeAction(s2t("fill"), d, DialogModes.NO);
        }
    }

    function getDescValue(d, p) {
        switch (d.getType(p)) {
            case DescValueType.OBJECTTYPE: return { type: t2s(d.getObjectType(p)), value: d.getObjectValue(p) };
            case DescValueType.LISTTYPE: return d.getList(p);
            case DescValueType.REFERENCETYPE: return d.getReference(p);
            case DescValueType.BOOLEANTYPE: return d.getBoolean(p);
            case DescValueType.STRINGTYPE: return d.getString(p);
            case DescValueType.INTEGERTYPE: return d.getInteger(p);
            case DescValueType.LARGEINTEGERTYPE: return d.getLargeInteger(p);
            case DescValueType.DOUBLETYPE: return d.getDouble(p);
            case DescValueType.ALIASTYPE: return d.getPath(p);
            case DescValueType.CLASSTYPE: return d.getClass(p);
            case DescValueType.UNITDOUBLE: return (d.getUnitDoubleValue(p));
            case DescValueType.ENUMERATEDTYPE: return { type: t2s(d.getEnumerationType(p)), value: t2s(d.getEnumerationValue(p)) };
            default: break;
        };
    }
}

 

2021-08-28_21-53-57.png

Untitled-1.jpg

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