Photoshop Index Color Script

← Previous Post

Next Post →

Intro

The Magic Wand is the key tool for extracting elements from an image. Clicking on a designated area, or, designated pixel, incorporates similarly colored pixels into a new selection.

Whenever I find myself restricted by the selections outputted by the Magic Wand, or if I just want to get some spontaneity in my selections, I’ll alter an image’s color information to determine subsequent selections that I make.

Sometimes I’ll do this is by converting to indexed color mode, experiment with the forfeiting of color information. Trying out dither options like diffusion, pattern, and noise can be affect what we see in our selections too. Observing the relationship between color information and magic wand selections, might help us drive/stylize the pixels of our image a certain way to influence selections we make later. I illustrate this workflow in this Photoshop script.

Overview of Photoshop Script

Described below is the sequence of actions taken by the script.

  1. Set image mode to indexed ( Image > Mode > Indexed Color... )

  2. Go into the color table ( Image > Mode > Color Table... ) and replace the first 3 colors with the colors: red, green, and blue.

  3. Set mode back to RGB ( Image > Mode > Indexed Color... ).

  4. For each color (red, green, blue), make a selection of that color. If a selection exists, create a new Photoshop layer and fill it with a shade of grey. Using the current selection, add a mask to each layer.

If a selection can’t be made from one of our colors (added into our color table), a layer will not be made. The script then moves onto the next color.

RicePatty1 normal RicePatty1 rgb RicePatty1 grey

RicePatty2 normal RicePatty2 rgb RicePatty2 grey

Code

#target photoshop
var doc = app.activeDocument;
var fuzz = 200;
var shadeNumber = 3;
var shadeValue = 110;

var colorRange = new Array();
colorRange[0] = {
    red: 255,
    green: 0,
    blue: 0
};
colorRange[1] = {
    red: 0,
    green: 255,
    blue: 0
};
colorRange[2] = {
    red: 0,
    green: 0,
    blue: 255
};

function convertToDuotone() {
    // write options for indexed color mode here 
    myObject = new IndexedConversionOptions();
    myObject.palette = Palette.LOCALADAPTIVE;
    // how many colors to split/filter the image into
    myObject.colors = shadeNumber;
    doc.changeMode(ChangeMode.INDEXEDCOLOR, myObject);
};

function convertToRGB() {
    doc.changeMode(ChangeMode.RGB);
}

function setColorTable() {
    var idsetd = charIDToTypeID("setd");
    var desc20 = new ActionDescriptor();
    var idnull = charIDToTypeID("null");
    var ref6 = new ActionReference();
    var idClr = charIDToTypeID("Clr ");
    var idClrT = charIDToTypeID("ClrT");
    ref6.putProperty(idClr, idClrT);
    desc20.putReference(idnull, ref6);
    var idT = charIDToTypeID("T   ");
    var list1 = new ActionList();
    for (var i = 0; i < shadeNumber; i++) {
        var tableColor = new ActionDescriptor();
        var idRd = charIDToTypeID("Rd  ");
        tableColor.putDouble(idRd, colorRange[i]['red']);
        var idGrn = charIDToTypeID("Grn ");
        tableColor.putDouble(idGrn, colorRange[i]['green']);
        var idBl = charIDToTypeID("Bl  ");
        tableColor.putDouble(idBl, colorRange[i]['blue']);
        var idRGBC = charIDToTypeID("RGBC");
        list1.putObject(idRGBC, tableColor);
    }
    desc20.putList(idT, list1);
    var idTrnI = charIDToTypeID("TrnI");
    desc20.putInteger(idTrnI, shadeNumber);
    executeAction(idsetd, desc20, DialogModes.NO);
}


convertToDuotone();

setColorTable();

convertToRGB();

doc.selection.deselect();


for (var i = 0; i < 3; i++) {

    var selectColour = new SolidColor();
    selectColour.rgb.red = colorRange[i]['red'];
    selectColour.rgb.green = colorRange[i]['green'];
    selectColour.rgb.blue = colorRange[i]['blue'];

    var scaleA = (selectColour.lab.a + 128.5) / 256;
    var desc11 = new ActionDescriptor();
    desc11.putInteger(charIDToTypeID("Fzns"), fuzz);
    var desc12 = new ActionDescriptor();
    desc12.putDouble(charIDToTypeID("Lmnc"), selectColour.lab.l);
    desc12.putDouble(charIDToTypeID("A   "), selectColour.lab.a + scaleA);
    desc12.putDouble(charIDToTypeID("B   "), selectColour.lab.b + scaleA);
    desc11.putObject(charIDToTypeID("Mnm "), charIDToTypeID("LbCl"), desc12);
    desc11.putObject(charIDToTypeID("Mxm "), charIDToTypeID("LbCl"), desc12);
    executeAction(charIDToTypeID("ClrR"), desc11, DialogModes.NO);
    if (hasSelection() == true) {
        var layerRef = doc.artLayers.add();

        var desc140 = new ActionDescriptor();
        desc140.putClass(charIDToTypeID('Nw  '), charIDToTypeID('Chnl'));
        var ref51 = new ActionReference();
        ref51.putEnumerated(charIDToTypeID('Chnl'), charIDToTypeID('Chnl'), charIDToTypeID('Msk '));
        desc140.putReference(charIDToTypeID('At  '), ref51);
        desc140.putEnumerated(charIDToTypeID('Usng'), charIDToTypeID('UsrM'), charIDToTypeID('RvlS'));
        executeAction(charIDToTypeID('Mk  '), desc140, DialogModes.NO);
        doc.activeChannels = [doc.channels[0], doc.channels[1], doc.channels[2]]

        var myColor = new SolidColor();
        myColor.rgb.red = myColor.rgb.green = myColor.rgb.blue = shadeValue;
        app.activeDocument.selection.selectAll();

        app.activeDocument.selection.fill(myColor, undefined, undefined, true);
        app.activeDocument.selection.fill(myColor);
        
        if ((shadeValue+36) > 255)
        {
            shadeValue = 255;
        } else {
            shadeValue += 36;
        };
    };
};

function hasSelection() {
    var ref = new ActionReference();
    ref.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    var docDesc = executeActionGet(ref);
    var hasSelection = docDesc.hasKey(stringIDToTypeID("selection"));
    return hasSelection;
};

doc.selection.deselect();