Skip to main content
Participating Frequently
February 28, 2025
Answered

Indesign script colorTransform methode incorrect return value

  • February 28, 2025
  • 4 replies
  • 1685 views

Hello,

I have the following problem in InDesign 2025.

I am trying to transform the CMYK color [41,46,56,36] to RGB color using the colorTransform method and the return value is [0,0,0] RGB color. Why? What am I not setting or doing wrong?

If I look at this color with the eyedropper in InDesign, it shows values ​​of R: 117 G:103 B:88

The value does not improve even if I try to convert it to Lab or HSB first

Regards: Árpad

Correct answer Marc Autret

Hi @árpádp3188668 

 

By one of those obscure whims that belong only to the Adobe dev team, the method app.colorTransform(…) expects and returns numbers in 0…1 — except for the LAB color space which still uses the original colorValue ranges (L: 0…100, a: -100..100, b: -100..100). So you need to properly downscale (then upscale) the values found in your Swatch/Color objects, as dictated by the specific color spaces under consideration.

 

Best is to have in your toolbox an adapter routine, like this:

 

 

function colorTransform(/*num[]*/vals,/*str|ColorSpace*/from,/*str|ColorSpace*/to,/*int=0*/dec,  a,k,i)
//----------------------------------
// vals :: array of numbers *as processed by Color.colorValue*, that is
//       - [0..255, 0..255, 0..255]         in RGB space
//       - [0..100, 0..100, 0..100, 0..100] in CMYK space
//       - [0..100, -128..127, -128..127]   in LAB space
//       - [0..360, 0..100, 0..100]         in HSB space
// (Rem: MixedInk is not supported by app.colorTransform.)
// from  :: source ColorSpace or key string ('RGB'|'CMYK'|'HSB'|'LAB')
// to    :: dest. ColorSpace or key string ('RGB'|'CMYK'|'HSB'|'LAB')
// dec   :: rounding decimal digits (use -1 to bypass rounding);
//          default is 0, i.e. rounding to the nearest integer.
// Returns the converted values as a new array of 3 or 4 numbers in
// the expected ranges (i.e. as processed by Color.colorValue).
// => num[]
{
   from = from.toString().toUpperCase();
   to = to.toString().toUpperCase();
   
   if( from==to ) return vals.slice();

   switch( from )
   {
      case 'RGB':
         // app.colorTransform() expects r,g,b values in 0..1 (!)
         // -> divide by 255
         a = [ vals[0]/255, vals[1]/255, vals[2]/255 ];
         break;

      case 'CMYK':
         // app.colorTransform() expects c,m,y,k values in 0..1 (!)
         // -> divide by 100
         a = [ .01*vals[0], .01*vals[1], .01*vals[2], .01*vals[3] ];
         break;

      case 'HSB':
         // app.colorTransform() expects h,s,b values in 0..1 (!)
         // -> divide h by 360 and s,b by 100
         a = [ vals[0]/360, .01*vals[1], .01*vals[2] ];
         break;

      case 'LAB':
         // app.colorTransform() expects L,a,b values as given in original range,
         // that is, L:0..100, a:-100..100, b:-100..100
         a = vals.slice();
         break;

      default:
         throw "Unsupported color space " + from;
   }

   try
   {
      a = app.colorTransform(a, ColorSpace[from], ColorSpace[to]);
   }
   catch(e)
   {
      throw "Unable to convert " + a + " from " + from + " to " + to + " [" + e + "]";
   }

   switch( to )
   {
      case 'RGB':
         // app.colorTransform() returns r,g,b values in 0..1 (!)
         // -> multiply by 255
         a[0]*=255; a[1]*=255; a[2]*=255;
         break;

      case 'CMYK':
         // app.colorTransform() returns c,m,y,k values in 0..1 (!)
         // -> multiply by 100
         a[0]*=100; a[1]*=100; a[2]*=100; a[3]*=100;
         break;

      case 'HSB':
         // app.colorTransform() returns h,s,b values in 0..1 (!)
         // -> multiply h by 360 and s,b by 100
         a[0]*=360; a[1]*=100; a[2]*=100;
         break;
      
      case 'LAB':
         // app.colorTransform() returns L,a,b values in original range,
         // that is, L:0..100, a:-100..100, b:-100..100

      default:;
   }
   
   
   if( 0 <= (dec|=0) )
   {
      k = Math.pow(10,dec);
      for(i=a.length ; i-- ; a[i]=Math.round(k*a[i])/k );
   }
   
   return a;
}

// TEST: Transform the CMYK color [41,46,56,36] to RGB
// ---
var res = colorTransform( [41,46,56,36], 'CMYK', 'RGB' );
alert( res ); // => 113,97,82

 

 

Best,

Marc

4 replies

Marc Autret
Marc AutretCorrect answer
Legend
March 1, 2025

Hi @árpádp3188668 

 

By one of those obscure whims that belong only to the Adobe dev team, the method app.colorTransform(…) expects and returns numbers in 0…1 — except for the LAB color space which still uses the original colorValue ranges (L: 0…100, a: -100..100, b: -100..100). So you need to properly downscale (then upscale) the values found in your Swatch/Color objects, as dictated by the specific color spaces under consideration.

 

Best is to have in your toolbox an adapter routine, like this:

 

 

function colorTransform(/*num[]*/vals,/*str|ColorSpace*/from,/*str|ColorSpace*/to,/*int=0*/dec,  a,k,i)
//----------------------------------
// vals :: array of numbers *as processed by Color.colorValue*, that is
//       - [0..255, 0..255, 0..255]         in RGB space
//       - [0..100, 0..100, 0..100, 0..100] in CMYK space
//       - [0..100, -128..127, -128..127]   in LAB space
//       - [0..360, 0..100, 0..100]         in HSB space
// (Rem: MixedInk is not supported by app.colorTransform.)
// from  :: source ColorSpace or key string ('RGB'|'CMYK'|'HSB'|'LAB')
// to    :: dest. ColorSpace or key string ('RGB'|'CMYK'|'HSB'|'LAB')
// dec   :: rounding decimal digits (use -1 to bypass rounding);
//          default is 0, i.e. rounding to the nearest integer.
// Returns the converted values as a new array of 3 or 4 numbers in
// the expected ranges (i.e. as processed by Color.colorValue).
// => num[]
{
   from = from.toString().toUpperCase();
   to = to.toString().toUpperCase();
   
   if( from==to ) return vals.slice();

   switch( from )
   {
      case 'RGB':
         // app.colorTransform() expects r,g,b values in 0..1 (!)
         // -> divide by 255
         a = [ vals[0]/255, vals[1]/255, vals[2]/255 ];
         break;

      case 'CMYK':
         // app.colorTransform() expects c,m,y,k values in 0..1 (!)
         // -> divide by 100
         a = [ .01*vals[0], .01*vals[1], .01*vals[2], .01*vals[3] ];
         break;

      case 'HSB':
         // app.colorTransform() expects h,s,b values in 0..1 (!)
         // -> divide h by 360 and s,b by 100
         a = [ vals[0]/360, .01*vals[1], .01*vals[2] ];
         break;

      case 'LAB':
         // app.colorTransform() expects L,a,b values as given in original range,
         // that is, L:0..100, a:-100..100, b:-100..100
         a = vals.slice();
         break;

      default:
         throw "Unsupported color space " + from;
   }

   try
   {
      a = app.colorTransform(a, ColorSpace[from], ColorSpace[to]);
   }
   catch(e)
   {
      throw "Unable to convert " + a + " from " + from + " to " + to + " [" + e + "]";
   }

   switch( to )
   {
      case 'RGB':
         // app.colorTransform() returns r,g,b values in 0..1 (!)
         // -> multiply by 255
         a[0]*=255; a[1]*=255; a[2]*=255;
         break;

      case 'CMYK':
         // app.colorTransform() returns c,m,y,k values in 0..1 (!)
         // -> multiply by 100
         a[0]*=100; a[1]*=100; a[2]*=100; a[3]*=100;
         break;

      case 'HSB':
         // app.colorTransform() returns h,s,b values in 0..1 (!)
         // -> multiply h by 360 and s,b by 100
         a[0]*=360; a[1]*=100; a[2]*=100;
         break;
      
      case 'LAB':
         // app.colorTransform() returns L,a,b values in original range,
         // that is, L:0..100, a:-100..100, b:-100..100

      default:;
   }
   
   
   if( 0 <= (dec|=0) )
   {
      k = Math.pow(10,dec);
      for(i=a.length ; i-- ; a[i]=Math.round(k*a[i])/k );
   }
   
   return a;
}

// TEST: Transform the CMYK color [41,46,56,36] to RGB
// ---
var res = colorTransform( [41,46,56,36], 'CMYK', 'RGB' );
alert( res ); // => 113,97,82

 

 

Best,

Marc

m1b
Community Expert
Community Expert
March 1, 2025

Thanks @Marc Autret, in my quick test I did notice that app.colorTransform was returning 0..1 numbers, but I was too silly to realise that it would also require 0..1 numbers, too! Haha.

- Mark

Marc Autret
Legend
March 2, 2025
quote

in my quick test I did notice that app.colorTransform was returning 0..1 numbers

 

Hi Mark, just keep in mind that the LAB color space is an exception to the rule, since it takes and returns 

L:0..100, a:-100..100, b:-100..100
m1b
Community Expert
Community Expert
February 28, 2025

Edit: I posted a script here originally, but I realised that it gives a bad result when there is text selected. I won't bother fixing it, I'll just delete it, because @Marc Autret's has found a much better way to do it, that doesn't have that problem. Please see Marc's post.

- Mark

Community Expert
February 28, 2025

can you give this one a try?

var doc = app.activeDocument;
var selectedColor;

if (app.selection.length > 0 && app.selection[0].fillColor) {
    selectedColor = app.selection[0].fillColor;
} else {
    var swatchName = prompt("Enter the name of a swatch to convert:", "");
    if (!swatchName) {
        alert("No swatch selected.");
        exit();
    }
    try {
        selectedColor = doc.colors.itemByName(swatchName);
        if (!selectedColor.isValid) throw new Error();
    } catch (e) {
        alert("Swatch not found.");
        exit();
    }
}

var originalModel = selectedColor.model; // Store original model (Process or Spot)
var originalSpace = selectedColor.space; // Store original color space
var cmykValues, rgbValues;

if (originalModel === ColorModel.SPOT) {
    // Convert Spot (Pantone) to Process CMYK
    selectedColor.model = ColorModel.PROCESS;
    selectedColor.space = ColorSpace.CMYK;
    cmykValues = selectedColor.colorValue;
} else if (originalSpace === ColorSpace.CMYK) {
    cmykValues = selectedColor.colorValue;
} else {
    alert("Selected color is neither CMYK nor Spot (Pantone).");
    exit();
}

// Convert CMYK to RGB
selectedColor.space = ColorSpace.RGB;
rgbValues = selectedColor.colorValue;

// Restore original colour settings
selectedColor.model = originalModel;
selectedColor.space = originalSpace;

alert(
    "CMYK: " + cmykValues.join(", ") + 
    "\nConverted RGB: " + rgbValues.join(", ")
);
Participating Frequently
February 28, 2025

Thank you very much!

I see your color space changing technique works great!

Community Expert
February 28, 2025

Can you share the script?

Participating Frequently
February 28, 2025
var cmykValues=[41,46,56,36], rgbValues=[]

     rgbValues=app.colorTransform(cmykValues,ColorSpace.CMYK,ColorSpace.RGB);

    alert(rgbValues)
Participating Frequently
February 28, 2025