Photoshop jsx to cut up mosaic colored layer to separate layers.

I have a rendered 3d image(many), with clear cut-up color-fields in a single layer, and want to cut up this single layer to multiple single layers for each color.

I want to parse the histogram, and get the main colors, however, the histogram is somewhat dirty with some antialias between colorfields.

What would be the mathematical concept to identify the main colors in the histogram?

An accumulator array and a threshold?

My hunch would be that operating on the source image would be easier than parsing part of the Photoshop UI to get an approximation of the histogram analysis that has been done. Although if you do want to just operate on the histogram, there is an app for that: http://www.aviz.fr/histomages

I made an object array of pixel by color.

It is painfully slow on Photoshop CC and unusable. (There is no getPixels in photoshop jsx).

Hmmm, maybe I need to work this from another angle, like a list of known colors? And pick from a list, if selection is empty, don’t distribute to layer… something like that…

// Set Adobe Photoshop CC 2015 to use pixels and display no dialogs
app.preferences.rulerUnits = Units.PIXELS
app.preferences.typeUnits = TypeUnits.PIXELS
app.displayDialogs = DialogModes.NO

var docRef = app.activeDocument;

var docWidth = 50;//docRef.width;
var docHeight = 50;//docRef.height;
var xPos = 0;
var yPos = 0;

app.activeDocument.colorSamplers.removeAll();

var myColorSampler = app.activeDocument.colorSamplers.add([0,0]);

var colorArray = {};
var myColor, rgbR,rgbG,rgbB,rgbString,count;

for(xPos = 0; xPos<docWidth; xPos++)
{
    for(yPos = 0; yPos<docHeight; yPos++)
    {
            myColorSampler.move([xPos,yPos]); 
            myColor = myColorSampler.color; 
            
            rgbString = myColor.rgb.red.toString() + "," +myColor.rgb.green.toString() + "," + myColor.rgb.blue.toString();
            
            if(colorArray[rgbString] )
            {
                count = colorArray[rgbString][0]+1;
                colorArray[rgbString] = [count, myColor];
            }else{
                colorArray[rgbString] = [1, myColor];
            }
    }
}

var keys = [];

for (var k in colorArray) {
  if (colorArray.hasOwnProperty(k)) {
    keys.push(k);
  }
}

keys.sort();

var len = keys.length;

for (var i = 0; i < len; i++) {
  var k = keys[i];
  alert(k + ':' + colorArray[k]);
}

alert("Done");

Solved.

The backwards strategy worked superfast (jsx superfast that is…). A list of colors and a copy merge function.

Here is the function for selecting a color range if anyone needs it, I only got LAB color from the script listener but thats ok, LAB is a better format.

function selLabColorRange(L,a,b, fuzz)
{
    var idClrR = charIDToTypeID( "ClrR" );
        var desc19 = new ActionDescriptor();
        var idFzns = charIDToTypeID( "Fzns" );
        desc19.putInteger( idFzns, fuzz );
        var idMnm = charIDToTypeID( "Mnm " );
            var desc20 = new ActionDescriptor();
            var idLmnc = charIDToTypeID( "Lmnc" );
            desc20.putDouble( idLmnc, L );
            var idA = charIDToTypeID( "A   " );
            desc20.putDouble( idA, a );
            var idB = charIDToTypeID( "B   " );
            desc20.putDouble( idB, b );
        var idLbCl = charIDToTypeID( "LbCl" );
        desc19.putObject( idMnm, idLbCl, desc20 );
        var idMxm = charIDToTypeID( "Mxm " );
            var desc21 = new ActionDescriptor();
            var idLmnc = charIDToTypeID( "Lmnc" );
            desc21.putDouble( idLmnc, L );
            var idA = charIDToTypeID( "A   " );
            desc21.putDouble( idA, a );
            var idB = charIDToTypeID( "B   " );
            desc21.putDouble( idB, b );
        var idLbCl = charIDToTypeID( "LbCl" );
        desc19.putObject( idMxm, idLbCl, desc21 );
        var idcolorModel = stringIDToTypeID( "colorModel" );
        desc19.putInteger( idcolorModel, 0 );
    executeAction( idClrR, desc19, DialogModes.NO );
}