I mostly work on creating Brand guidelines using InDesign where I have to add multiple brand colors. Each color is shown on a page as a rectangle background and a text box that shows the color codes with its Hex, RGB, and CMYK code.
It gets quite hectic as I have mostly 10-30 colors and manually does all these for each color.
I'm new to Javascript but somehow managed to get some color codes using JSX with the help of ChatGPT but I can't get CMYK color if the document type is RGB and if the document type is CMYK then I'm unable to get RGB.
I'm only interested in the color values present on the color picker and I know depending on the document type CMYK values might be different but that doesn't matter as of now.
Working on it on Windows PC so no Applescript option :(.
Here is my current code:
if (app.selection.length > 0) {
for (var i = 0; i < app.selection.length; i++) {
var selectedObject = app.selection[i];
if (selectedObject instanceof Rectangle && selectedObject.fillColor !== null) {
var fillColor = selectedObject.fillColor;
if (fillColor.space === ColorSpace.RGB) {
var hexCode = getHexCode(fillColor);
var rgbCode = getRGBCode(fillColor);
var cmykCode = "N/A"; // CMYK not applicable for RGB colors
createColorCodeTextFrame(selectedObject, hexCode, rgbCode, cmykCode);
} else if (fillColor.space === ColorSpace.CMYK) {
var hexCode = "N/A"; // Hex not applicable for CMYK colors
var rgbCode = getRGBCode(fillColor);
var cmykCode = getCMYKCode(fillColor);
createColorCodeTextFrame(selectedObject, hexCode, rgbCode, cmykCode);
}
}
}
}
function createColorCodeTextFrame(selectedObject, hexCode, rgbCode, cmykCode) {
var frameWidth = 280; // Width of the text frame
var frameHeight = 120; // Height of the text frame
var topMargin = 40; // Top margin
var leftMargin = 40; // Left margin
// Calculate the coordinates for the bounding box
var boundingBox = [
selectedObject.geometricBounds[0] + topMargin, // Top position with margin
selectedObject.geometricBounds[1] + leftMargin, // Left position with margin
selectedObject.geometricBounds[0] + topMargin + frameHeight, // Bottom position with margin
selectedObject.geometricBounds[1] + leftMargin + frameWidth // Right position with margin
];
var textFrame = selectedObject.parentPage.textFrames.add({
geometricBounds: boundingBox,
contents: "RGB: " + rgbCode + "\nCMYK: " + cmykCode + "\nHex: " + hexCode,
textFramePreferences: {
autoSizingType: AutoSizingTypeEnum.OFF
}
});
textFrame.fillColor = "None";
textFrame.strokeColor = "None";
var basicParagraphStyle = app.activeDocument.paragraphStyles.itemByName("Basic Paragraph");
if (basicParagraphStyle.isValid) {
textFrame.paragraphs.everyItem().appliedParagraphStyle = basicParagraphStyle;
}
textFrame.textFramePreferences.verticalJustification = VerticalJustification.CENTER_ALIGN;
}
function getHexCode(color) {
var colorValues = color.colorValue;
var hexCode = "#" + decimalToHex(colorValues[0]) + decimalToHex(colorValues[1]) + decimalToHex(colorValues[2]);
return hexCode;
}
function decimalToHex(decimal) {
var hex = Math.round(decimal).toString(16);
return hex.length === 1 ? "0" + hex : hex;
}
function getRGBCode(color) {
var colorValues = color.colorValue;
var rgbCode = Math.round(colorValues[0]) + ", " + Math.round(colorValues[1]) + ", " + Math.round(colorValues[2]);
return rgbCode;
}
function getCMYKCode(color) {
var colorValues = color.colorValue;
var cmykCode = colorValues[0] + "%, " + colorValues[1] + "%, " + colorValues[2] + "%, " + colorValues[3] + "%";
return cmykCode;
}
I would appreciate any help in fixing the issue.
As far as I can tell, you can create the temp color with the same values, convert it into any space (CMYK or RGB) and then get the numbers from this temp color:
// create the temp color with the same properties as 'fillColor'
var temp_color = app.activeDocument.colors.add({
name: fillColor.name + '_temp',
colorValue: fillColor.colorValue,
space: fillColor.space,
});
if (fillColor.space === ColorSpace.RGB) {
var hexCode = getHexCode(fillColor);
var rgbCode = getRGBCode(fillColor);
temp_color.space = ColorSpace.CMYK; // convert the temp color into CMYK
var cmykCode = getCMYKCode(temp_color); // get the numbers
createColorCodeTextFrame(selectedObject, hexCode, rgbCode, cmykCode);
}
else if (fillColor.space === ColorSpace.CMYK) {
temp_color.space = ColorSpace.RGB; // convert the temp color into RGB
var hexCode = getHexCode(temp_color); // get the numbers
var rgbCode = getRGBCode(temp_color); // get the numbers
var cmykCode = getCMYKCode(fillColor);
createColorCodeTextFrame(selectedObject, hexCode, rgbCode, cmykCode);
}
temp_color.remove(); // remove the temp color
Or you can replace the the code above with these lines:
// get the properties from 'fillColor'
var temp_color_properties = fillColor.properties;
// create the temp CMYK color
temp_color_properties.name = fillColor.name + '_temp_cmyk';
var temp_cmyk_color = app.activeDocument.colors.add(temp_color_properties);
temp_cmyk_color.space = ColorSpace.CMYK;
// create the temp RGB color
temp_color_properties.name = fillColor.name + '_temp_rgb';
var temp_rgb_color = app.activeDocument.colors.add(temp_color_properties);
temp_rgb_color.space = ColorSpace.RGB;
// get the numbers
var hexCode = getHexCode(temp_rgb_color);
var rgbCode = getRGBCode(temp_rgb_color);
var cmykCode = getCMYKCode(temp_cmyk_color);
// remove the temp colors
temp_cmyk_color.remove();
temp_rgb_color.remove();
createColorCodeTextFrame(selectedObject, hexCode, rgbCode, cmykCode);
And probably you need to add Math.round()
to CMYK values as well as it's done for RGB values.
Results:
Update. The script uses current measuring units of the document. So if you're using inches it can get you the weird results like this:
You can temporary change units to pixels with these lines at the start of your code:
var doc = app.activeDocument;
var orig_x_units = doc.viewPreferences.horizontalMeasurementUnits;
var orig_y_units = doc.viewPreferences.verticalMeasurementUnits;
doc.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.PIXELS;
doc.viewPreferences.verticalMeasurementUnits = MeasurementUnits.PIXELS;
And then change the units back to orinal with these lines at the end of your script:
doc.viewPreferences.horizontalMeasurementUnits = orig_x_units;
doc.viewPreferences.verticalMeasurementUnits = orig_y_units;