Is anyone using core.convertColor?

It seems to be about 2-3x faster than using a SolidColor. Still much slower than doing conversions entirely in javascript, but is uses the application level ColorSettings for the conversions which is not possible otherwise. I have not been not able to find where ColorConversionModel is defined so I reverse engineered this enum:

const ColorConversionModel = Object.freeze({RGB: 3, HSB: 4, CMYK: 5, LAB: 6, GRAYSCALE: 7});

Also, what is up with some of these objects? The naming conventions are all over the place. “grain” in RGBColor? “yellowColor” in CMYKColorClass? hue: { _unit: “angleUnit”, _value: h } in HSBColorClass?

function rgbTo(r, g, b, model) {
    return (core.convertColor({ _obj: "RGBColor", blue: b, grain: g, red: r }, model));
}
function labTo(l, a, b, model) {
    return (core.convertColor({ _obj: "labColor", a: a, b: b, luminance: l,}, model));
}
function cmykTo(c, m, y, k, model) {
    return (core.convertColor({ _obj: "CMYKColorClass", black: k, cyan: c, magenta: m, yellowColor: y }, model));
}
function hsbTo(h, s, b, model) {
    return (core.convertColor({ _obj: "HSBColorClass", brightness: b, hue: { _unit: "angleUnit", _value: h }, saturation: s }, model));
}
function grayscaleTo(gray, model) {
    return (core.convertColor({ _obj: "grayscale", gray: gray }, model));
}

It is faster because it skips some steps. I think SolidColor validates the values passed in.

To explain grain vs green… you would have to go like +20-30 years back :smiley:
They used TypeID for property keys which is number of 4 bytes. And you can fit only 4 characters in it, which is not a lot. But it will be fast. So you have “green” and “grain” both are 5 characters but it has to be 4. So you do something like “Grn “ …and if you do the same for both they both get same TypeID. In extend script this 4 bytes key was called CharID

Then also StringID was a thing… it could have any length and anytime you see property in UXP action descriptor that does not start with $ it is StringID… they are assigned on the go meaning the number is not fixed unlike CharID. Starts at 0 and increments. Unless the same key already exists as CharID then number is calculated from characters.

So you have “Grn “ but you don’t know if you should translate it back as “grain” or “green” because both have same value. You could assume based on context where you are in… but it can cause many issues elsewhere… so it is better to keep it as it is :smiley:

There are few more properties like this. E.g. “paint” vs “point”

Ideally, we would have perfect DOM for everything and you would not need to care about this low-level stuff.

1 Like

Thanks Jarda, that makes sense. Is ColorConversionModel defined anywhere public?

I don’t think you can replicate color conversions without PS API. It take color settings in account. And for Lab it is really difficult black box even without color settings. It maybe use lookup tables… I am not sure. And I think most of the “professional color handling” is key the part of intelectual property I guess.

If you want better speed maybe you could try to cache like 1000 most frequent colors. But it could be pretty much usless… depends on image.

Maybe you could hack performance with: https://developer.adobe.com/photoshop/uxp/2022/ps_reference/media/imaging/#photoshopimagedata

By converting multiple values at once. But not all color modes are available.

Yes thanks! That’s exactly what I have been doing when I need to get LAB data for a whole image, and that works super fast. changeMode(constants.DocumentMode.LAB) then getPixels()

I had an impression it would be possible to read RGB document and it to Lab in memory without changing the document itself.