0

Please note that I'm a complete beginner and this is my first coding question ever. If this is more appropriate on another site, tell me.

I want to automate a process were the program select a colour and change it to another one.

This is the code I have, thank to the script listener:

var id159 = charIDToTypeID( "ClrR" );
var desc34 = new ActionDescriptor(); 
var id160 = charIDToTypeID( "Fzns" );
desc34.putInteger( id160, 0 ); 
var id161 = charIDToTypeID( "Mnm " );
    var desc35 = new ActionDescriptor();
    var id162 = charIDToTypeID( "Rd  " );
    desc35.putDouble( id162, 0.000000 );
    var id163 = charIDToTypeID( "Grn " );
    desc35.putDouble( id163, 255.000000 );
    var id164 = charIDToTypeID( "Bl  " );
    desc35.putDouble( id164, 0.000000 );
var id165 = charIDToTypeID( "RGBC" );
desc34.putObject( id161, id165, desc35 ); 
var id166 = charIDToTypeID( "Mxm " );
    var desc36 = new ActionDescriptor();
    var id167 = charIDToTypeID( "Rd  " );
    desc36.putDouble( id167, 0.000000 );
    var id168 = charIDToTypeID( "Grn " );
    desc36.putDouble( id168, 255.000000 );
    var id169 = charIDToTypeID( "Bl  " );
    desc36.putDouble( id169, 0.000000 );
var id170 = charIDToTypeID( "RGBC" );
desc34.putObject( id166, id170, desc36 ); executeAction( id159, desc34, DialogModes.NO );

When I run this in Photoshop it does work but since I have a lot of colours to select, I want to know

  1. If there is a more efficient way to do it, using less lines of code. It could be either with the colour range or another tool.
  2. I would prefer to use hexadecimal values but I have no idea how to write it. I managed to change it to RGB but it was originally using Lab colours.

In this example, the hex would be 00ff00

  • 2
    This might help you... I made this as an example to someone else some time ago: gist.github.com/joonaspaakko/347c270f15bc1d11efe9 - It uses the list of hex codes defined at the top to change the foreground color in PS. It writes a text file in the same folder where the script is to keep track of which color was used (based on index number). So every time you run the script it picks the next color, applies it to foreground, writes new number in the temp file and loops around once you get to the end. I believe it was tested in PS CC. – Joonas Jan 30 '18 at 20:26
  • 1
  • 1
    Looked at the suggested duplicate and read again what you said. I want to point out that there are a couple "Global Swatch Extensions" for PS: ColorKit and Prisma. If you know how Global swatches work in Indesign or Illustrator, you know how these extensions work. A short explanation: You use the extension to apply/link a color to a text or a shape and if you ever change the color from the extension, it's changed anywhere that color has been applied. – Joonas Jan 30 '18 at 21:58
  • @Joonas Thanks! I will have a look at it when some more time. – Vincent Jan 31 '18 at 15:33
1

This is more of a long commentary than an answer. I am not sure selecting color range is the best way to replace color but yes you could do this.

  1. Number of lines dont make more efficient code! One line of code can well be less efficient than a 100. Besides theres code below code so its not like your scripting language is pedal to the metal. Also the scripting API is inherently inefficient if you care for speed then its time to start wirting c++ and use photoshop plugin API.

    However, i will take it you mean more practical. Yes we can define some functions to make it easier to read and use, call and slightly more condense. Although making it more practical will increase the length slightly, but this is not meaningfull for you. So let us refactor the code:

    #target photoshop
    
    selectColorRange(
        RGBc(0.0, 255.0, 0.0),
        RGBc(0.0, 255.0, 0.0)
    );
    
    
    /******* Support functions *******/
    
    function cTID(s) { return app.charIDToTypeID(s); }
    function sTID(s) { return app.stringIDToTypeID(s); }
    
    function RGBc(r, g, b) {
        var color = new ActionDescriptor();
            color.putDouble( cTID("Rd  "), r);
            color.putDouble( cTID("Grn "), g);
            color.putDouble( cTID("Bl  "), b);   
        return color
    }
    
    function selectColorRange(color1, color2){
        var desc = new ActionDescriptor(); 
        desc.putInteger(cTID("Fzns"), 0 ); 
        desc.putObject( cTID("Mnm "), cTID("RGBC"), color1 ); 
        desc.putObject( cTID("Mxm "), cTID("RGBC"), color2 ); 
        executeAction( cTID("ClrR"), desc, DialogModes.NO );
    }
    

    So now from your point of view the code is only selectColorRange. Obviously, if you only ever intend to select only one color then you could change selectColorRange to only take one input.

    Also even if adobe had this as a javascipt function or object then your code wouldnt be more then 3 lines shorter most likely. Since objects need to be populated anyway.

  2. Well this is pretty easy, you can find many implementations of this by googling. So lot us define a function to do this:

    function hexC(hex) {
        // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
        hex = hex.substring(1,7)
        bigint = parseInt(hex, 16);
        var color = new ActionDescriptor()
            color.putDouble(cTID("Rd  "), (bigint >> 16) & 255);
            color.putDouble(cTID("Grn "), (bigint >> 8) & 255);
            color.putDouble(cTID("Bl  "), bigint & 255);
        return color
    }
    

    So you would call hexC like this,

    colorReplace(
         hexC("#00ff00"),
         hexC("#00ff00")
    );
    

    instead of RGBc.

Ok, so now we have all pieces in your code in place. If you have many colors then just call a for loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.