Copy link to clipboard
Copied
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!
3 Correct answers
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
...
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
...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.
Explore related tutorials & articles
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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;
}
Copy link to clipboard
Copied
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;
}
Copy link to clipboard
Copied
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.

