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

Fill shape colour by adding DMC number

Community Beginner ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

Hi, I have to create a huge number of tables similar to the one attached. All I get is the DMC numbers on an Excel sheet. I can copy and paste the numbers to Photoshop easily. But have to drag and drop the swatches to rectangles in front of DMC numbers one by one. Some tables have more than 50 colours and it's a very tedious process. Is it possible to automate this to fill the colours only feeding the DMC numbers?

 

You can find the hexcode for DMC here:

DMC Cotton Floss converted to RGB Values.csv

 

Eg:

DMC 310 = #000000 (Black)

DMC 321 = #c72b3b (Red)

 

Screenshot 2021-08-06 at 12.51.31.png

TOPICS
Actions and scripting , macOS

Views

297

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 1 Correct answer

Community Expert , Aug 14, 2021 Aug 14, 2021

I have a script that I used in a similar situation. I didn't try to make it universal and write clean code, I just needed to make about 12000 color swatches from tabular data.

 

The script requires some preparation:

1. Create a template for one row of your table. Decorate as you like.

2021-08-14_23-41-08.png

2. Save your colors to the csv table (choose the type of separator to your taste, the script now uses a semicolon, but you can change it). The first row of the table is the headers.
2021-08-15_00-04-15.png

3. The script substitutes 2 types of

...

Likes

Translate

Translate
Community Expert ,
Aug 06, 2021 Aug 06, 2021

Copy link to clipboard

Copied

You would probably need to write a script to accomplish this.

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

Copy link to clipboard

Copied

Yes. Is there anyone who can write a script for this?

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 Expert ,
Aug 14, 2021 Aug 14, 2021

Copy link to clipboard

Copied

I have a script that I used in a similar situation. I didn't try to make it universal and write clean code, I just needed to make about 12000 color swatches from tabular data.

 

The script requires some preparation:

1. Create a template for one row of your table. Decorate as you like.

2021-08-14_23-41-08.png

2. Save your colors to the csv table (choose the type of separator to your taste, the script now uses a semicolon, but you can change it). The first row of the table is the headers.
2021-08-15_00-04-15.png

3. The script substitutes 2 types of values ​​- text and color. 
Text values ​​are entered into a layer of type text. Color is assigned only to pixel layers. For the script to try to substitute the value, the layer name in the file must exactly match the title from the table.
There are no problems with the text (the name of the headers in the table can be arbitrary), but the color can be set in only two ways:
a) there are three columns in the table with the names Red, Green, Blue - in this case, the corresponding layer for filling with color should be called RGB
b) there is one column in the table with the name HEX - in this case, the corresponding layer for filling with color should be called HEX
2021-08-14_23-39-51.png

4. Save your template to any directory, put one or more CSV files with substitution values ​​in the same directory.
2021-08-14_23-42-15.png
5. Open the template in Photoshop, run the script.
The script will generate files representing individual rows of your table in template folder (by default in *.psd, but it possible write save function in any format)
2021-08-14_23-42-47.png

 

Since I have no idea what your layout requirements are, you can put them into a table either manually or using other scripts (for example, the contact sheet does a good job with this task).

2021-08-14_23-49-01.png2021-08-14_23-48-24.png

 

 

 

 

 

 

#target photoshop

app.doProgress('', 'main()')

function main() {
    try {
        var doc = new AM('document'),
            lr = new AM('layer'),
            strDelimiter = ';'; // change csv div here if needed

        if (doc.hasProperty('numberOfLayers')) {
            var len = doc.getProperty('numberOfLayers'),
                names = [];
            for (var i = 1; i <= len; i++) {
                if (lr.getProperty('layerSection', i, true).value == 'layerSectionEnd') continue;
                var layerKind = lr.getProperty('layerKind', i, true)
                // process only pixel and text layers
                if (layerKind == 1 || layerKind == 3) {
                    names.push({ name: lr.getProperty('name', i, true).toLowerCase(), id: lr.getProperty('layerID', i, true), layerKind: layerKind })
                }
            }
        } else throw (new Error('No open template!'))

        if (names.length) {
            var source = doc.hasProperty('fileReference') ? doc.getProperty('fileReference') : null,
                ext = source ? decodeURI(source.name).match(/\..*$/)[0] : null,
                pth = Folder(source.path);
        } else throw (new Error('No matching layer names found!'))

        if (pth) {
            var csv = pth.getFiles(/\.(csv)$/i);
        } else throw (new Error('Cannot find csv because template file do not saved yet!'))

        if (csv.length) {
            do {
                var fileContent = [],
                    currentFile = csv.shift(),
                    fileName = decodeURI(currentFile.name).replace(/\.csv/i, '');

                currentFile.open("r");
                do {
                    var line = currentFile.readln()
                    if (line != "") fileContent.push(line)
                } while (!currentFile.eof)
                currentFile.close()

                if (fileContent.length) {
                    var csvContent = [];
                    do {
                        csvContent.push(splitCSVLine(fileContent.shift(), strDelimiter))
                    } while (fileContent.length)
                } else throw (new Error('CSV file is empty!'))

                var headers = csvContent.shift(),
                    numberOfLines = csvContent.length;
                csvObject = {};
                do {
                    var cur = headers.shift().toLowerCase();
                    csvObject[cur] = [];
                    for (var i = 0; i < csvContent.length; i++) {
                        csvObject[cur].push(csvContent[i].shift())
                    }
                } while (headers.length)

                for (var x = 1; x <= numberOfLines; x++) {
                    app.updateProgress(x, numberOfLines)
                    app.changeProgressText(x + ' of ' + numberOfLines)

                    var newFilename = fileName + ' ' + (('0000' + x).slice(-4));
                    for (var i = 0; i < names.length; i++) {
                        var cur = names[i];
                        if (cur.layerKind == 1 && (cur.name.match(/RGB/i) || cur.name.match(/HEX/i))) {

                            if (cur.name.match(/RGB/i)) {
                                if (csvObject['red'].length && csvObject['green'].length && csvObject['blue'].length) {
                                    var c = new SolidColor;
                                    newFilename += ' R' + csvObject['red'][0] + ' G' + csvObject['green'][0] + ' B' + csvObject['blue'][0];
                                    with (c.rgb) {
                                        red = csvObject['red'].shift();
                                        green = csvObject['green'].shift();
                                        blue = csvObject['blue'].shift();
                                    }
                                }
                            } else if (cur.name.match(/HEX/i) && csvObject['hex']) {
                                if (csvObject['hex'].length) {
                                    var c = new SolidColor;
                                    newFilename += ' HEX' + csvObject['hex'][0];
                                    c.rgb.hexValue = csvObject['hex'].shift()
                                }
                            }

                            if (c) lr.changeFillEffect(c.rgb.red, c.rgb.green, c.rgb.blue, cur.id)
                            continue;
                        }

                        if (cur.layerKind == 3) {
                            if (csvObject[cur.name]) {
                                if (csvObject[cur.name].length) {
                                    newFilename += ' ' + csvObject[cur.name][0]
                                    lr.changeTextKey(csvObject[cur.name].shift(), cur.id)
                                }
                                continue;
                            }
                        }
                    }
                    activeDocument.saveAs(File(pth + '/' + newFilename.replace(/\.[^\.]+$/, '')))
                }
            } while (csv.length)

            activeDocument.close()
            app.open(source)

        } else throw (new Error('Cannot find csv file in parent folder of template!'))
    } catch (e) { alert(e); return; }
}

function splitCSVLine(strData, strDelimiter) {
    strDelimiter = (strDelimiter);
    var objPattern = new RegExp(
        (
            "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
            "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
            "([^\"\\" + strDelimiter + "\\r\\n]*))"
        ),
        "gi"
    );
    var arrData = [],
        arrMatches = null;

    while (arrMatches = objPattern.exec(strData)) {
        var strMatchedDelimiter = arrMatches[1];

        if (strMatchedDelimiter != undefined) {
            if (
                strMatchedDelimiter.length &&
                strMatchedDelimiter !== strDelimiter
            ) {
                arrData.push();
            }
        }
        var strMatchedValue;
        if (arrMatches[2]) {
            strMatchedValue = arrMatches[2].replace(
                new RegExp("\"\"", "g"),
                "\""
            );
        } else {
            strMatchedValue = arrMatches[3];
        }
        arrData.push(strMatchedValue);
    }

    return (arrData);
}

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'));
        try { return executeActionGet(r).hasKey(property) } catch (e) { return false }
    }

    this.descToObject = function (d) {
        var o = {}
        for (var i = 0; i < d.count; i++) {
            var k = d.getKey(i)
            o[t2s(k)] = getDescValue(d, k)
        }
        return o
    }

    this.changeFillEffect = function (red, green, blue, id) {
        (r = new ActionReference()).putProperty(s2t("property"), p = s2t("layerEffects"));
        r.putIdentifier(s2t("layer"), id);
        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);

        (d = new ActionDescriptor()).putDouble(s2t("red"), red);
        d.putDouble(s2t("green"), green);
        d.putDouble(s2t("blue"), blue);
        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);
    }

    this.changeTextKey = function (text, id) {
        (r = new ActionReference()).putProperty(s2t('property'), p = s2t('textKey'));
        r.putIdentifier(s2t('layer'), id);
        if (executeActionGet(r).hasKey(p)) {
            var textKey = executeActionGet(r).getObjectValue(p);

            textKey.putString(s2t('textKey'), text);
            (r = new ActionReference()).putIdentifier(s2t('layer'), id);
            (d = new ActionDescriptor()).putReference(s2t('null'), r);
            d.putObject(s2t('to'), s2t('textLayer'), textKey);
            executeAction(s2t('set'), 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;
        };
    }
}

 

 

 

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

Copy link to clipboard

Copied

Wow... Looks like this is exactly what I wanted. I'm gonna try this with my layout and see. I will let you know how it goes. Thank you very much 🙂

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
LEGEND ,
Aug 20, 2021 Aug 20, 2021

Copy link to clipboard

Copied

LATEST

If you tried the code and it does work for you, please mark appropriate answer as correct 😉

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