Copy link to clipboard
Copied
Hello friends
I have a document with magenta color (magenta=100) and I am looking for a script that will turn it into a spot color whose name will be "cutcontour" (magenta=100 too)
Hi @aviel222, here is a modified version of the script I wrote for you on this thread. I think it will do what you want. Try to understand what is happening in the changeColor function. You can configure what you want to do there to some extent. Note that currently, this script will create the "CutContour" spot colour if it isn't in document already (see the call to my makeSpot function).
- Mark
/**
* Replaces colors of items in document.
* Currently configured via the 'changeColor'
* r
...
Copy link to clipboard
Copied
The spot color already exists in the document.
Copy link to clipboard
Copied
So you want to find any fillColor or strokeColor that is C0 M100 Y0 K0 and replace with the spotColor "cutcontour"?
Copy link to clipboard
Copied
only stroke color. yes
Copy link to clipboard
Copied
Hi @aviel222 ,
Try following version
function main() {
var doc = app.activeDocument;
var _originalColor = new CMYKColor();
_originalColor.cyan = 0;
_originalColor.magenta = 100;
_originalColor.yellow = 0;
_originalColor.black = 0;
doc.selection = null;
doc.defaultStrokeColor = _originalColor;
app.executeMenuCommand("Find Stroke Color menu item");
var _replacementSpot = doc.spots['cutcontour']
doc.defaultStrokeColor = _replacementSpot.color;
}
main();
Copy link to clipboard
Copied
Copy link to clipboard
Copied
can someone help me
Copy link to clipboard
Copied
charu? m1b?
Copy link to clipboard
Copied
Hi @aviel222, here is a modified version of the script I wrote for you on this thread. I think it will do what you want. Try to understand what is happening in the changeColor function. You can configure what you want to do there to some extent. Note that currently, this script will create the "CutContour" spot colour if it isn't in document already (see the call to my makeSpot function).
- Mark
/**
* Replaces colors of items in document.
* Currently configured via the 'changeColor'
* replacer function to:
* (a) change stroke [C=0, M=100, Y=0, K=0] to 'CutContour' spot.
* (b) not change [C=100 M=0 Y=0 K=0] or [C=0 M=100 Y=0 K=0] (even in spot color)
* (c) change 10% black or lighter to white
* (d) change anyhting else to 100% black
* @discussion https://community.adobe.com/t5/illustrator-discussions/make-100-black-in-document/m-p/13482548
* @discussion https://community.adobe.com/t5/illustrator-discussions/change-color-swatch-to-other-color-swatch/m-p/13491958
* Note: you can customise which colors are excluded by editing the `changeColor` function or writing your own replacer.
*/
(function () {
if (!confirm('Do you want to replace colors?'))
return;
var doc = app.activeDocument,
items = doc.pageItems,
white = makeWhite(),
black = makeBlack(),
cutContourSpot = makeSpot(doc, 'CutContour', [0, 100, 0, 0]);
for (var i = 0; i < items.length; i++)
replaceColors(items[i], changeColor);
/**
* Returns a color based on the given color.
* A `replacer` function for replaceColors.
* @param {Color} c - the input color.
* @param {Boolean} isFillColor - whether the input color is a fillColor.
* @returns {Color} - the output color
*/
function changeColor(startColor, isFillColor) {
var c = startColor;
if (c.typename == 'SpotColor')
c = c.spot.color;
if (
(
c.typename == 'GrayColor'
&& c.gray <= 10
)
|| (
c.typename == 'CMYKColor'
&& c.cyan == 0
&& c.magenta == 0
&& c.yellow == 0
&& c.black <= 10
)
)
return white;
else if (
isFillColor !== true
&& c.typename == 'CMYKColor'
&& c.cyan == 0
&& c.magenta == 100
&& c.yellow == 0
&& c.black == 0
)
return cutContourSpot;
else if (
(
c.typename == 'CMYKColor'
&& c.cyan == 100
&& c.magenta == 0
&& c.yellow == 0
&& c.black == 0
)
|| (
c.typename == 'CMYKColor'
&& c.cyan == 0
&& c.magenta == 100
&& c.yellow == 0
&& c.black == 0
)
)
return c;
else
return black;
};
/**
* Replace `item`s basic colors with
* a supplied `replacementColor` but only
* if `filterFunction` returns true;
* @author m1b
* @version 2023-01-17
* @param {PageItem} item - the item to replace colors of.
* @param {Function} replacer - function that returns a replacement color.
*/
function replaceColors(item, replacer) {
if (item == undefined)
throw Error('replaceColors: No item supplied.');
var noColor = "[NoColor]",
colorables = [];
// collect all the colorables
if (item.constructor.name == 'PathItem') {
colorables.push(item);
}
else if (
item.constructor.name == 'CompoundPathItem'
&& item.pathItems
) {
colorables.push(item.pathItems[0]);
}
else if (
item.constructor.name == 'TextFrame'
&& item.textRanges
) {
for (var i = item.textRanges.length - 1; i >= 0; i--)
colorables.push({
fillColor: item.textRanges[i].characterAttributes.fillColor,
strokeColor: item.textRanges[i].characterAttributes.strokeColor
});
}
if (colorables.length > 0)
for (var i = 0; i < colorables.length; i++) {
if (
colorables[i].hasOwnProperty('fillColor')
&& colorables[i].fillColor != noColor
&& (
!colorables[i].hasOwnProperty('filled')
|| colorables[i].filled == true
)
&& colorables[i].fillColor != undefined
)
colorables[i].fillColor = replacer(colorables[i].fillColor, true);
if (
colorables[i].hasOwnProperty('strokeColor')
&& colorables[i].strokeColor != noColor
&& (
colorables[i].constructor.name == 'CharacterAttributes'
|| colorables[i].stroked == true
)
&& colorables[i].strokeColor != undefined
)
colorables[i].strokeColor = replacer(colorables[i].strokeColor, false);
}
else if (item.constructor.name == 'GroupItem') {
for (var i = 0; i < item.pageItems.length; i++)
replaceColors(item.pageItems[i], replacer);
}
};
/**
* Returns a black color.
* @returns {CMYKColor}
*/
function makeBlack() {
return makeColor([0, 0, 0, 100]);
};
/**
* Returns a white color.
* @returns {CMYKColor}
*/
function makeWhite() {
return makeColor([0, 0, 0, 0]);
};
function makeColor(breakdown) {
var c;
if (breakdown.length == 1) {
c = new GrayColor();
c.gray = breakdown[0];
}
else if (breakdown.length == 3) {
c = new RGBColor();
c.red = breakdown[0];
c.green = breakdown[1];
c.blue = breakdown[2];
}
else if (breakdown.length == 4) {
c = new CMYKColor();
c.cyan = breakdown[0];
c.magenta = breakdown[1];
c.yellow = breakdown[2];
c.black = breakdown[3];
}
return c;
};
function makeSpot(doc, name, breakdown, colorModel) {
// check if exists in document
var newColor = getThing(doc.swatches, 'name', name);
if (newColor != undefined)
return newColor.color;
// or create it
var newSpot = doc.spots.add();
newSpot.name = name;
newSpot.colorType = colorModel || ColorModel.SPOT;
var col = makeColor(breakdown);
if (col == undefined)
throw Error('makeSpot: could not make color (breakdown: ' + breakdown + ').');
newSpot.color = col;
newColor = new SpotColor();
newColor.spot = newSpot;
return newColor;
};
function getThing(things, key, value) {
for (var i = 0; i < things.length; i++)
if (things[i][key] == value)
return things[i];
};
})();
Copy link to clipboard
Copied
Thank you @m1b for the excellent script. I understand how most of it works and I am using it to successfully change colors in my work. I have only gotten it to change a few colors (noteably, pure white (0,0,0,0) and pure cyan, magenta, and pure black) to colors of my choosing. So far I haven't been able to figure out why the script isn't changing any of the other colors in my document. I modified the script to change the pure colors, but have not been able to figure out why it isn't working on mixed CMYK colors. The colors I am trying to change are the same color model as other colors that the script is changing (CMYK, Process, etc). If you have any thoughts about what might be happening, I would greatly appreciate it. Thanks!
Copy link to clipboard
Copied
Hi @SuperPower, did you re-configure the script for the colors you want? It could be mis-configured but it's hard for me to know with out seeing your configuration code at least.
Also, have a look at my script here. It is newer and I think it might be generally a more useful script. Otherwise, send me the breakdowns you are interested in capturing, and I'll make a filter function that matches your sample colors.
- Mark
Copy link to clipboard
Copied
Thank you, Mark. I will try the new script. I was able to configure your earlier script to change any color in the document from one CMYK color to another. The problem is that this was only working for pure C, pure M, pure Y, pure K, and although I was able to reconfigure the script to change other colors, this only worked for new objects that I created. In my test doc I have a rectangle that has this color: C=70 M=0 Y=64 K=0. If I create a new rectangle and assign it these same values, the new rectangle will change successfully, but the original rectangle will not. My hunch is that the original rectangles are not registering as colorable items, or the if statements I am using in the changeColor function do not cover all the possible color models and color types in the document. Thank you again for your help and for sharing all this great work! I will try your updated script.
Below is a modified portion of your script, the changeColor function:
/**
* Returns a color based on the given color.
* A `replacer` function for replaceColors.
* @Param {Color} c - the input color.
* @Param {Boolean} isFillColor - whether the input color is a fillColor.
* @Returns {Color} - the output color
*/
function changeColor(startColor, isFillColor) {
var c = startColor;
if (c.typename == 'SpotColor')
c = c.spot.color;
if (
c.typename == 'SpotColor'
&& c.cyan == 70
&& c.magenta == 0
&& c.yellow == 64
&& c.black == 0
)
return revisedyellow;
if (
c.typename == 'CMYKColor'
&& c.cyan == 70
&& c.magenta == 0
&& c.yellow == 64
&& c.black == 0
)
return revisedyellow;
if (
c.cyan == 70
&& c.magenta == 0
&& c.yellow == 64
&& c.black == 0
)
return revisedgreen;
if (
c.typename == 'CMYKColor'
&& c.cyan == 0
&& c.magenta == 100
&& c.yellow == 0
&& c.black == 0
)
return black;
if (
c.typename == 'CMYKColor'
&& c.cyan == 0
&& c.magenta == 0
&& c.yellow == 100
&& c.black == 0
)
return revisedgreen;
if (
c.typename == 'CMYKColor'
&& c.cyan == 0
&& c.magenta == 30
&& c.yellow == 86
&& c.black == 0
)
return revisedyellow;
if (
c.typename == 'CMYKColor'
&& c.cyan == 0
&& c.magenta == 100
&& c.yellow == 0
&& c.black == 0
)
return black;
if (
c.typename == 'CMYKColor'
&& c.cyan == 0
&& c.magenta == 0
&& c.yellow == 0
&& c.black == 0
)
return white;
if (
c.typename == 'CMYKColor'
&& c.cyan == 100
&& c.magenta == 0
&& c.yellow == 0
&& c.black == 0
)
return revisedyellow;
if (
isFillColor !== true
&& c.typename == 'CMYKColor'
&& c.cyan == 70
&& c.magenta == 0
&& c.yellow == 64
&& c.black == 0
)
return revisedyellow;
if (
c.typename == 'CMYKColor'
&& c.cyan == 70
&& c.magenta == 0
&& c.yellow == 64
&& c.black == 0
)
return revisedyellow;
else
return c;
};
Copy link to clipboard
Copied
Hi @SuperPower, I'm not sure why "this only worked for new objects that I created". That suggests there's something more going on here than meets the eye. If the problem persists, please post a sample file with the issue, so I can look into it.
- Mark
Copy link to clipboard
Copied
Hello @m1b. We identified why some of the objects were not changing color as expected. We created an alert to display each object's CMYK value and discovered that some objects' CMYK values contained unexpected decimal values. Any objects with these decimals were not being handled as expected by the script. To resolve it we used Math.round to round the CMYK values to whole numbers without decimals. Thanks again for your help!
Copy link to clipboard
Copied
Good work. Yes using rounding is one way to solve that problem. Another way, which I prefer, is to compare the difference of the values against a tolerance constant, eg.
Math.abs(a – b) < 0.001