javascriptautomationadobebackground-coloradobe-indesign

InDesign Script to Populate Rectangle BG Color Codes into TextBox


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.

Color Codes of the rectangle bg

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.


Solution

  • 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:

    enter image description here

    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:

    enter image description here

    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;