Skip to main content
Inspiring
August 25, 2022

P: Very similar color not applying to TextItem

  • August 25, 2022
  • 6 replies
  • 685 views
  • Photoshop version: 23.4.2 Release
  • OS: Windows 10 Enterprise 1803


Steps to reproduce:

  1. Create a javascript (attached in .txt format) which applies a color to an ArtLayer TextItem.
  2. Choose an new color that is very similar to the existing color. Ex: #FFFFFF >> #FFFEFE

 

Expected result: Color is applied to the TextItem.
Actual result: Color is not applied.

This topic has been closed for replies.

6 replies

Inspiring
August 30, 2022

@CShubert Try this test:

 

1. Create text with the hex color 010101.

2. Open Color Picker for the text.

3. Edit the hex color to 000000 via the # field and click OK.

4. Reopen the Color Picker for the text or test the text color with eyedropper.

 

Expected: Text color 000000 is applied.

Actual: Text color remains 010101.

CShubert
Community Manager
Community Manager
August 30, 2022

Hi all,

 

While the team is looking into this, a possible workaround would be is to input hex values like ffee in the color picker. This may not work with an action or JavaScript.

 

Thank you,

CShubert
Community Manager
Community Manager
August 29, 2022

The team is looking into this issue.

 

Thank you,

Legend
August 25, 2022

@Lumigraphics This workaround works. Also, we can replace the color if we do not update, but recreate the layer:

#target photoshop
var newColor = [255, 255, 255], // [R,G,B]
    s2t = stringIDToTypeID,
    t2s = typeIDToStringID;

(r = new ActionReference()).putProperty(s2t('property'), p = s2t('textKey'));
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
if (executeActionGet(r).hasKey(p)) {
    var textKey = executeActionGet(r).getObjectValue(p),
        tList = textKey.getList(s2t('textStyleRange')),
        pList = textKey.getList(s2t('paragraphStyleRange')),
        defaultStyle = (p = pList.getObjectValue(0).getObjectValue(s2t('paragraphStyle'))).hasKey(s2t('defaultStyle')) ?
            p.getObjectValue(s2t('defaultStyle')) : new ActionDescriptor(),
        l = new ActionList(),
        d = new ActionDescriptor();
    for (var x = 0; x < tList.count; x++) {
        k = tList.getObjectValue(x)
        if (k.getObjectValue(s2t('textStyle')).hasKey(s2t('color'))) {
            s = copyDesc(defaultStyle, k.getObjectValue(s2t('textStyle')))
            c = s.getObjectValue(s2t('color'))
            var d = new ActionDescriptor();
            d.putDouble(s2t('red'), newColor[0])
            d.putDouble(s2t('grain'), newColor[1])
            d.putDouble(s2t('blue'), newColor[2])
            s.putObject(s2t('color'), s2t('RGBColor'), d)
            k.putObject(s2t('textStyle'), s2t('textStyle'), s)
        }
        l.putObject(s2t('textStyleRange'), k)
    }
    if (d.count) {
        (ref = new ActionReference()).putClass(s2t("textLayer"));
        (desc = new ActionDescriptor()).putReference(s2t("null"), ref);
        (desc1 = new ActionDescriptor()).putString(s2t("textKey"), '');
        desc1.putList(s2t("textStyleRange"), new ActionList());
        desc.putObject(s2t("using"), s2t("textLayer"), desc1);
        executeAction(s2t("make"), desc, DialogModes.NO);
   
        (ref = new ActionReference()).putEnumerated( s2t( "layer" ), s2t( "ordinal" ), s2t( "backwardEnum" ));
        (desc = new ActionDescriptor()).putReference( s2t( "null" ), ref );
        executeAction( s2t( "delete" ), desc, DialogModes.NO )

        textKey.putList(s2t('textStyleRange'), l)
        var d = new ActionDescriptor();
        (r = new ActionReference()).putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
        d.putReference(s2t('null'), r);
        d.putObject(s2t('to'), s2t('textLayer'), textKey);
        executeAction(s2t('set'), d, DialogModes.NO);
    }
}

function copyDesc(from, to) {
    for (var i = 0; i < from.count; i++) {
        var k = from.getKey(i);
        if (to.hasKey(k)) continue;
        switch (from.getType(k)) {
            case DescValueType.ALIASTYPE: to.putPath(k, from.getPath(k)); break;
            case DescValueType.BOOLEANTYPE: to.putBoolean(k, from.getBoolean(k)); break;
            case DescValueType.CLASSTYPE: to.putClass(k, from.getClass(k)); break;
            case DescValueType.DOUBLETYPE: to.putDouble(k, from.getDouble(k)); break;
            case DescValueType.INTEGERTYPE: to.putInteger(k, from.getInteger(k)); break;
            case DescValueType.LISTTYPE: to.putList(k, from.getList(k)); break;
            case DescValueType.RAWTYPE: to.putData(k, from.getData(k)); break;
            case DescValueType.STRINGTYPE: to.putString(k, from.getString(k)); break;
            case DescValueType.LARGEINTEGERTYPE: to.putLargeInteger(k, from.getLargeInteger(k)); break;
            case DescValueType.REFERENCETYPE: to.putReference(k, from.getReference(k)); break;
            case DescValueType.OBJECTTYPE: to.putObject(k, from.getObjectType(k), from.getObjectValue(k)); break;
            case DescValueType.ENUMERATEDTYPE: to.putEnumerated(k, from.getEnumerationType(k), from.getEnumerationValue(k)); break;
            case DescValueType.UNITDOUBLE: to.putUnitDouble(k, from.getUnitDoubleType(k), from.getUnitDoubleValue(k)); break;
        }
    }
    return to
}

(the same code stops updating the color if we remove the command to create a new layer)

Legend
August 25, 2022

What if you change by a large amount then do a second color change to the desired value?

R:255 G:0 B:0 -> R:128 G:128 B:128 -> R:254 G:0 B:0 as an example

Legend
August 25, 2022
 The result is always like this:
"color": {
    "_obj": "RGBColor",
    "blue": 253.99530351161957,
    "grain": 253.99530351161957,
    "red": 255
}
But if we do it manually, then everything goes well. Perhaps we are dealing with some kind of internal optimization (since updating text styles can sometimes be a very time-consuming operation).