Copy link to clipboard
Copied
Hello all,
I need to export the fillColor of a paragraph style via scripting.
I can get the fillColor property of the paragraph style, and can also convert CMYK to Hex. However, I do realize that the color values shown in InDesign are in whatever Color Space the document is using.
My question is, is there a native API to convert the color values to a web safe color value? If not, how do I go about mapping the colors?
Additionally, I see that Adobe internally knows how to convert it to a proper hex color (screenshot attached - note the color property in the Export Tagging pane). If I cannot use some native API, is there a way to access the text in that pane?
Thanks all, in advance!
Win! It worked!!!
Here's the complete solution -
Assuming the original color is stored in a variable named color
:
...var color = passedInColor; //the original color that we wish to convert.
// Create a temporary color instance that we'll use to extract updated colorValues.
var scratchColor = workingDoc.colors.add({
model: color.model,
space: color.space,
colorValue: color.colorValue
});
// Now, we force a
Copy link to clipboard
Copied
You need to (1) convert the CMYK color space to RGB, then (2) find the closest 'web safe' value.
Converting CMYK to RGB is just a matter of changing the color space, but you will find it's as accurate as all color space conversions (i.e., "not very"). However, there is no reasonable alternative.
Changing the RGB values from 0..255 to the 216 color "web safe" palette is a matter of maths: there are 6 levels of R,G,B each. Divide by 51, round, multiply by 51 again and you have right value. Note that your example shows #aaaad0, which is not one of the web safe colors. The nearest equivalent would be #9999cc.
Copy link to clipboard
Copied
Thanks for your reply!
I'm actually not looking to transform it to a web safe palette. I'm looking for True Color (24 bit, 256 values for each R, G and B). I'm simply using chrome for testing the color; and making sure it looks the way it does in InDesign.
The CMYK that I had was 33, 30, 3 and 0, which translates to an RGB of 171, 179, 247, which then translates to a hex value of #abb3f7.
However, what I'm looking for is how do I map that CMYK color space (U.S. Web Coated SWOP V2), to an RGB, such that I get an output of 170, 170, 208 (aaaad0). If Adobe's doing it internally, so precisely, there's got to be a way!
Copy link to clipboard
Copied
Ah okay; you mentioned "web safe color" and I wondered why, as that is So 1995.
It seems that internal conversion is not exposed to scripting. Off the record: using my trusty old CS4, I get different values for 33,30,3,0: 170,169,206, which is #AAA9CE in hex. So, very close to what you are seeing in the Export Tags dialog. I did not see any differences when assigning different color profiles, or possibly I did not do that the right way.
Copy link to clipboard
Copied
Oh no! I'm so sorry! I thought I had removed that part in the question, and made it "True Color", but I guess that's why I shouldn't write posts in a hurry! Long chain of edits that led to web safe colors. I also cannot seem to find an edit button to fix it!
Thanks for pointing that out btw!
Anyways, thanks a bunch for your prompt responses! You're right - I spent a couple hours yesterday going through almost the entire APIs and didn't see anything that caught my eye. Thought I might have missed out on something. BUT!!!! Progress - I *just* found out that if I account for the tint value, and then edit a current CMYK color to RGB color through the "Swatch Options" window in InDesign, I can get the exact RGB color that I'm looking for. That being said, I'm looking to see whether I can do this:
I cannot seem to find a method to "create" a "new instance of Color", so I'm going to use the "duplicate" method of an existing color, and update it's color values, and use it as a scratch instance for converting all my colors.
If this works, I'll certainly update the post so that the community may make use of it!
Copy link to clipboard
Copied
Win! It worked!!!
Here's the complete solution -
Assuming the original color is stored in a variable named color
:
var color = passedInColor; //the original color that we wish to convert.
// Create a temporary color instance that we'll use to extract updated colorValues.
var scratchColor = workingDoc.colors.add({
model: color.model,
space: color.space,
colorValue: color.colorValue
});
// Now, we force adobe's internal color conversion mechanism to trigger by changing the scratchColor's color space.
scratchColor.space = ColorSpace.RGB;
var updatedValues = scratchColor.colorValue; // Updated values now has the properly mapped and converted RGB values.
// You may need to round off the R, G and B values in the updatedValues array.
// And that's it!
Why am I not surprised that it had to be a hacky work around?! *sigh*. Working on this platform has been so so so frustrating! I do hope adobe gets its act together!
Copy link to clipboard
Copied
Good to see!
I'm having the same issue nowadays.
I need to get CMYK values, RGB values and HEX value from a specific color swatch.
Could you show the way on how to convert RGB/CMYK to HEX?
Thanks in advance.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi @brian_p_dts , If I run that code I don’t get any useful conversions. This returns #ffffff—white not black
var n = cmykToHex(0,0,0,100);
$.writeln(n)
Copy link to clipboard
Copied
@rob day Aha. There was a bug in the OP that I fixed in my snippet, but failed to document. In the main CMYK function, we should be pointing to Number(k) not Number(m)
black = 100 * Number(k);
Copy link to clipboard
Copied
Now 50|0|50|0 moss green returns #00ff00, which is not in any CMYK gamut
var n = cmykToHex(50,0,50,0);
$.writeln(n)
//returns #00ff00
I don‘t think you can get an accurate or color managed conversion with a JS function. The script I posted below is using the document’s color management to get accurate conversions.
Copy link to clipboard
Copied
My code returns the Color Picker values. So for PANTONE 3514 the returned string is:
PANTONE 3514 C:
Lab: 79|14|91
Coated GRACoL 2006 (ISO 12647-2:2004) = 4|29|100|0
sRGB IEC61966-2.1 = 245|183|0
HEX: #F5B700
The Color Picker Values:
Copy link to clipboard
Copied
I guess you're right. I must have only used the rgbToHex conversion last time I looked this up. It's been a while.
Copy link to clipboard
Copied
Yes the reason that works is there’s no conversion to another color space—hex is just an alternate RGB notation.
Copy link to clipboard
Copied
Hi @lfcorullon , Are you really trying to get a Web Safe conversion, which seems to be what the OP was looking for in 2014?
For accurate color managed conversions, the source color should be a device independent Lab color. If the source is an RGB or CMYK color its appearance (and conversion values) would change depending on the source color’s assigned profile.
So you could use the Pantone Solid (Lab) swatches as the source and get accurate color managed conversions into your document’s assigned color spaces. Here getValues(color) is expecting a Lab swatch as the parameter—PANTONE Orange 021 in this example. My document’s assigned RGB and CMYK profiles are sRGB and Coated GRACoL, so getValue(lc) returns:
var doc = app.activeDocument;
//a Lab swatch
var lc = doc.swatches.itemByName("PANTONE Orange 021 C");
//document profiles
var rgbp = doc.rgbProfile;
var cmykp = doc.cmykProfile;
$.writeln(getValues(lc))
/**
* Gets the swatch values as text
* @ param the color to get
* @ return string for color list
*
*/
function getValues(theColor){
//var s = "";
var s = theColor.name + ":\r"
theColor.model = ColorModel.PROCESS;
var labval = theColor.colorValue;
s = s + "Lab: " + getValueString(labval) + "\r";
var cmykCon = theColor.duplicate();
cmykCon.space = ColorSpace.CMYK
var cmykval = cmykCon.colorValue;
s = s + cmykp + " = " + getValueString(cmykval) + "\r";
cmykCon.remove();
var rgbCon = theColor.duplicate();
rgbCon.space = ColorSpace.RGB;
var rgbval = rgbCon.colorValue;
s = s + rgbp + "= " + getValueString(rgbval) + "\r";
rgbCon.remove();
s = s + "HEX: " + convertRGB(Math.round(rgbval[0]), Math.round(rgbval[1]), Math.round(rgbval[2])) + "\r";
return s
}
/**
* The Color Value to set as a string with | dividers
* @ param the value array
* @ return string 0|0|0
*
*/
function getValueString(val){
var s = ""
for (var i = 0; i < val.length; i++){
s = s + Math.round (val[i]) + "|";
}
s = s.substring(0, s.length-1)
return s
}
/**
* Converts 8-bit RGB values to Hex
* @ param red 0-255
* @ param green 0-255
* @ param blue 0-255
* @ return hex string value
*
*/
function convertRGB(r,g,b){
var h1 = toHex(r)
if (h1.length == 1) {
h1 = "0" + h1
}
var h2 = toHex(g)
if (h2.length == 1) {
h2 = "0" + h2
}
var h3 = toHex(b)
if (h3.length == 1) {
h3 = "0" + h3
}
return "#" + h1 + h2 + h3
}
/**
* The Hex value of the provided value
* @ param the 8-bit value 0-255
* @ return hex string conversion
*/
function toHex(d) {
var r = d % 16;
if (d - r == 0) {
return toChar(r);
}
return toHex((d - r) / 16) + toChar(r);
}
/**
* A Hex character value
* @ param number
* @ return hex character
*
*/
function toChar(n) {
const alpha = "0123456789ABCDEF";
return alpha.charAt(n);
}
Copy link to clipboard
Copied
Awesome, thank you so much!!!!!!
Both toHex and toChar functions are all I need.
Copy link to clipboard
Copied
@DerKäse (btw. funny name) – there is an add() method for colors that will take a Object Color as argument.
Use that for your purpose.
Here an example for RGB:
var myDoc = app.documents[0];
var myColorName = "myNewRGBColor";
if(!myDoc.swatches.itemByName(myColorName).isValid){
var myNewColor = myDoc.colors.add(
{
name:myColorName,
colorValue:[255,255,0], //A bright yellow
model:ColorModel.PROCESS,
space:ColorSpace.RGB
}
);
};
Here one for CMYK:
var myDoc = app.documents[0];
var myColorName = "myNewCMYKColor";
if(!myDoc.swatches.itemByName(myColorName).isValid){
var myNewColor = myDoc.colors.add(
{
name:myColorName,
colorValue:[0,0,100,0], //A bright yellow
model:ColorModel.PROCESS,
space:ColorSpace.CMYK
}
);
};
Hope, that helps…
Uwe
Copy link to clipboard
Copied
Oops, too late… 😉
Uwe
Copy link to clipboard
Copied
Thanks a bunch anyway! This is corroboration that I'm doing it the right way!
Copy link to clipboard
Copied
Oh! One more thing I forgot to add!
Always cleanup after yourselves guys!
// Make sure you delete the scratch color once you're done with it!
scratchColor.remove();
Hah! Glad you get the name Laubender!!
Copy link to clipboard
Copied
Not to spoil your triumph, but:
What makes you so sure about your assumption, that all rules in the color conversion mechanism defined in your color settings of InDesign are applied? Eg. in my tests in the UI of InDesign I'm getting confusing results when changing a CMYK swatch to an RGB one:
InDesign CMYK Swatch:
0,0,100,0 CMYK (+ ISO Coated v2 300%) => sRGB = 251,224,21
0,0,100,0 CMYK (+ ISONewspaper26v4) => sRGB = 251,224,21
In my tests both conversions yield the same values.
And in my opinion that could not be right!
Take PhotoShop and do a conversion for the same CMYK values with different CMYK ICC-Profiles.
Check the converted values. They will be different.
PhotoShop Pixel Area filled with 0,0,100,0 CMYK:
0,0,100,0 CMYK (+ ISO Coated v2 300%) => sRGB = 251,224,21
0,0,100,0 CMYK (+ ISONewspaper26v4) => sRGB = 248,221,0
Your values might vary depending on the conversion module (Adobe (ACE) vs. Apple CMM) or the color conversion priority (perceptive vs. relative color metric etc.pp.).
(I ran all my tests with InDesign CS5.5 and PhotoShop CS5.1)
Uwe
Copy link to clipboard
Copied
Good question! And this is an awesome test!
So firstly, apropos this specific use case (the reason why I'm writing the script); I'm provided with standard color settings; thereby always using U.S. Web Coated (SWOP) v2. So it seems to *visually* work.
Now, considering the broader question of color settings, which is good, because we (or others) might use this under different use cases: I'm doing this on CS6.
When I go to Edit > Convert to Profile (check the preview box), and select a different profile, my color values change, and the way the color looks is also different. Owing to that, the RGB output is different.
I tried another test, wherein I changed my color setting to Coated FOGRA39(ISO 12647-2:2004), created a new swatch, gave it the same CMYK values as before, and the converted RGB values were different.
Are you using a different method/test case of changing these?
Copy link to clipboard
Copied
Yes. Could be, that something changed from CS5.5 (my version I did the tests) to CS6. Or its something in the color conversion policies. Whatever, I will do some more tests tomorrow. It's too late here in Germany right now (11 pm) and I need some sleep.
Uwe