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

Illustrator Scripting: create a Color Group + create / add swatches from selection

Community Expert ,
Oct 01, 2023 Oct 01, 2023

Scripters!

I wonder if it is possible to create a Color Group and create / add Swatches from all colors of a Selection to it (by Script)?!

 

I know it can be done by creating an Action then calling it by Script but I would like do do this task using a Script only.

 

Any ideas? Anyone?

Nils

 

PS. as always: JavaScript solutions only!

 

 

TOPICS
Scripting
408
Translate
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 3 Correct answers

Guide , Oct 02, 2023 Oct 02, 2023

Not extensively tested.

var doc = app.activeDocument;

// get (selected) paths
var paths = [];
recurse(doc.selection);
function recurse(items) {
    for (var i = 0; i < items.length; i++) {
        if (items[i].typename == "PathItem") {
            paths.push(items[i]);
        } else if (items[i].typename == "GroupItem") {
            recurse(items[i].pageItems);
        } else if (items[i].typename == "CompoundPathItem") {
            recurse(items[i].pathItems);
        }
    }
}

// get color
...
Translate
Community Expert , Oct 03, 2023 Oct 03, 2023

Hi femkeblanco,

thanks for your great input! Your Script seems to work well (just added a line so the "No Color" is not collected.

 

I played around to add Global Colors instead.

Now I*m tying to give the swatches their CMYK values as names.

 

However there is an error with my grouped object (2 rectangles, 1 does not have a stroke at all, 1 does have one, the group itself does have a stroke appearance (so this might be worst case but maybe there is a solution for it?)

 

Please see attached file

...
Translate
Enthusiast , Oct 03, 2023 Oct 03, 2023

You have a typing error " m=" + myY (yellow instead of magenta)

 

spots[g].name = "c="+myC+" m="+myM+" y="+myY+" k="+myK;

 

As for the appearance of the red group. From the scripts we can't read the color of the stroke. For that we would have to make a copy of the group, call the "Expand Appearance" command app.executeMenuCommand('expandStyle') (CS6+) for the selected copy of the group and then check the colors of the resulting objects. And then delete the expanded group.

Translate
Adobe
Enthusiast ,
Oct 01, 2023 Oct 01, 2023

It is possible. I can think of the following solution: we get all colors of selected objects (fills and strokes) as arrays. We remove equal arrays (equal colors). Then we create swatches in color group with collected channel values (rgb or cmyk). If necessary, we convert these swatches to spots.

Translate
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 ,
Oct 02, 2023 Oct 02, 2023

Not extensively tested.

var doc = app.activeDocument;

// get (selected) paths
var paths = [];
recurse(doc.selection);
function recurse(items) {
    for (var i = 0; i < items.length; i++) {
        if (items[i].typename == "PathItem") {
            paths.push(items[i]);
        } else if (items[i].typename == "GroupItem") {
            recurse(items[i].pageItems);
        } else if (items[i].typename == "CompoundPathItem") {
            recurse(items[i].pathItems);
        }
    }
}

// get colors
var colors = [];
for (var i = 0; i < paths.length; i++) {
    if (!isInArray(paths[i].strokeColor, colors)) {
        colors.push(paths[i].strokeColor);
    }
    if (!isInArray(paths[i].fillColor, colors)) {
        colors.push(paths[i].fillColor);
    }
}

// get swatches
var swatches = [];
for (var i = 0; i < colors.length; i++) {
    var swatch = doc.swatches.add();
    swatch.color = colors[i];
    for (var j = 0; j < doc.swatches.length; j++) {
        if (areEqual(colors[i], doc.swatches[j].color)) {
            swatch.name = doc.swatches[j].name;
            break;
        }
    }
    swatches.push(swatch);
}

// create swatchGroup
var swatchGroup = doc.swatchGroups.add();
swatchGroup.name = "Custom";
for (var i = 0; i < swatches.length; i++) {
    swatchGroup.addSwatch(swatches[i]);
}

function isInArray(e, a) {
  for (var i = 0; i < a.length; i++) {
    if (areEqual(e, a[i])) {
      return true;
    }
  }
  return false;
}
function areEqual(o1, o2) {
    for (var k in o1) {
        if (o1.hasOwnProperty(k)) {
            if (!o2.hasOwnProperty(k)) return false;
            if (o1[k] != o2[k]) return false;
        }
    }
    for (var k in o2) {
        if (o2.hasOwnProperty(k)) {
            if (!o1.hasOwnProperty(k)) return false;
            if (o1[k] != o2[k]) return false;
        }
    }
    return true;
}

 

Translate
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 ,
Oct 03, 2023 Oct 03, 2023

Hi femkeblanco,

thanks for your great input! Your Script seems to work well (just added a line so the "No Color" is not collected.

 

I played around to add Global Colors instead.

Now I*m tying to give the swatches their CMYK values as names.

 

However there is an error with my grouped object (2 rectangles, 1 does not have a stroke at all, 1 does have one, the group itself does have a stroke appearance (so this might be worst case but maybe there is a solution for it?)

 

Please see attached file (rename .pdf in .ai)

 

Here's the Script so far (will add a test.ai > rename .pdf as attachment):

 

var docRef = app.activeDocument;

// get (selected) paths
var paths = [];
recurse(docRef.selection);
function recurse(items) {
    for (var i = 0; i < items.length; i++) {
        if (items[i].typename == "PathItem") {
            paths.push(items[i]);
        } else if (items[i].typename == "GroupItem") {
            recurse(items[i].pageItems);
        } else if (items[i].typename == "CompoundPathItem") {
            recurse(items[i].pathItems);
        }
    }
}

// get colors
var colors = [];
for (var i = 0; i < paths.length; i++) {
    if (!isInArray(paths[i].strokeColor, colors)) {
        colors.push(paths[i].strokeColor);
    }
    if (!isInArray(paths[i].fillColor, colors)) {
        colors.push(paths[i].fillColor);
    }
}

// get spots
var spots = [];
for (var i = 0; i < colors.length; i++) {
    if (colors[i] != "[NoColor]") {
        var spot = docRef.spots.add();
        spot.color = colors[i];
        for (var j = 0; j < docRef.spots.length; j++) {
            if (areEqual(colors[i], docRef.spots[j].color)) {
                spot.name = docRef.spots[j].name;
                break;
            }
        }
        spots.push(spot);
    }
}

// create swatchGroup
var swatchGroup = docRef.swatchGroups.add();
swatchGroup.name = "my Colors";
for (var g = 0; g < spots.length; g++) {
    swatchGroup.addSpot(spots[g]);
    var myCMYK = spots[g].color;
    var myC = Math.round(myCMYK.cyan);
    var myM = Math.round(myCMYK.magenta);
    var myY = Math.round(myCMYK.yellow);
    var myK = Math.round(myCMYK.black);
    spots[g].name = "c="+myC+" m="+myY+" y="+myY+" k="+myK;
}

function isInArray(e, a) {
  for (var i = 0; i < a.length; i++) {
    if (areEqual(e, a[i])) {
      return true;
    }
  }
  return false;
}
function areEqual(o1, o2) {
    for (var k in o1) {
        if (o1.hasOwnProperty(k)) {
            if (!o2.hasOwnProperty(k)) return false;
            if (o1[k] != o2[k]) return false;
        }
    }
    for (var k in o2) {
        if (o2.hasOwnProperty(k)) {
            if (!o1.hasOwnProperty(k)) return false;
            if (o1[k] != o2[k]) return false;
        }
    }
    return true;
}

 

Translate
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
Enthusiast ,
Oct 03, 2023 Oct 03, 2023
LATEST

You have a typing error " m=" + myY (yellow instead of magenta)

 

spots[g].name = "c="+myC+" m="+myM+" y="+myY+" k="+myK;

 

As for the appearance of the red group. From the scripts we can't read the color of the stroke. For that we would have to make a copy of the group, call the "Expand Appearance" command app.executeMenuCommand('expandStyle') (CS6+) for the selected copy of the group and then check the colors of the resulting objects. And then delete the expanded group.

Translate
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