Skip to main content
Participating Frequently
June 14, 2021
Answered

Get color from selected area

  • June 14, 2021
  • 3 replies
  • 6849 views

Hello.

Please help in solving the following problem:

 

I need to pick up color with a dropper from a pre-selected randomly shaped area, probably quite small relative to the image and having no known position on the canvas, the current layer.
This needs to be done automatically, without manual clicks.

 

I haven't found ways to do this in PS itself without human intervention, and I have no experience in scripting, but scripting seems to be the correct solution to the problem. It would be great to have a ready-made script for such an operation.

 

Thank.

This topic has been closed for replies.
Correct answer r-bin

function get_average_color(color)

 

from here: Auto picking the most distinct accent color from an image

 

UPD.

 

Короче. По ссылке - глючная реплика со старого форума, скрипты там все нерабочие.

Вот готовый скрипт.

 

 

 

get_average_color(app.foregroundColor);

////////////////////////////////////////////////////////////
function get_average_color(color, x, y)
    {
    try {
        if (x != undefined && y != undefined) app.activeDocument.selection.select([[x,y],[x+1,y],[x+1,y+1],[x,y+1]], SelectionType.REPLACE); 
        
        var chnl = 3;
        if (app.activeDocument.mode == DocumentMode.CMYK) chnl = 4;

        if (app.activeDocument.mode == DocumentMode.GRAYSCALE) chnl = 1;

        var lm = new Array();
        var px = new Array();

        for (var i = 0; i < chnl; i++)
            {
            var hst = get_histogram(i+1);
            var l = 0;
            var p = 0;

            if (!hst) { return false; }

            for (var n in hst) { l += hst[n] * n; p += hst[n]; }  

            hst = null;

            lm.push(l);
            px.push(p);
            }

        if (app.activeDocument.mode == DocumentMode.RGB)
            {
            var r =lm[0]/px[0]; 
            var g =lm[1]/px[1]; 
            var b =lm[2]/px[2];

            with (color.rgb) { red = Math.round(r); green = Math.round(g); blue = Math.round(b); };
            }
        else if (app.activeDocument.mode == DocumentMode.LAB)
            {
            var _l = lm[0]/px[0] * 100/255; 
            var _a = lm[1]/px[1] - 128; 
            var _b = lm[2]/px[2] - 128;

            with (color.lab) { l = Math.round(_l); a = Math.round(_a); b = Math.round(_b); };
            }
        else if (app.activeDocument.mode == DocumentMode.CMYK)
            {
            var c = 100 - lm[0]/px[0] * 100/255; 
            var m = 100 - lm[1]/px[1] * 100/255; 
            var y = 100 - lm[2]/px[2] * 100/255;
            var k = 100 - lm[3]/px[3] * 100/255;

            with (color.cmyk) { cyan = Math.round(c); magenta = Math.round(m); yellow = Math.round(y); black = Math.round(k); };
            }
        else if (app.activeDocument.mode == DocumentMode.GRAYSCALE)
            {
            var _l = 100 - lm[0]/px[0] * 100/255; 

            with (color.gray) { gray = Math.round(_l);  };
            }
        else { alert("Unsupported color mode", "Error", true); return false; }

        if (x != undefined && y != undefined) app.activeDocument.selection.deselect();

        return true;
        }
    catch (e) { alert(e); }
    }

////////////////////////////////////////////////////////////
function get_histogram(n)
    {
    try {
        var r = new ActionReference();
        r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("histogram"));

        if (typeof(n) == "string")
            r.putName(stringIDToTypeID("channel"), n);
        else
            {
            if (app.activeDocument.mode == DocumentMode.RGB)
                {
                switch (n)
                    {       
                    case -1: r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;

                    case 0:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("RGB"  )); break;
                    case 1:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("red"  )); break;
                    case 2:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("green")); break;
                    case 3:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("blue" )); break;
   
                    default: r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;
                    }
                }
            else if (app.activeDocument.mode == DocumentMode.LAB)
                {
                switch (n)
                    {
                    case -1: 
                    case 0:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("lab"      )); break;
                    case 1:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("lightness")); break;
                    case 2:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("a"        )); break;
                    case 3:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("b"        )); break;
   
                    default: r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;
                    }
                }
            else if (app.activeDocument.mode == DocumentMode.CMYK)
                {
                switch (n)
                    {
                    case -1: r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;

                    case 0:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("CMYK"   )); break;
                    case 1:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("cyan"   )); break;
                    case 2:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("magenta")); break;
                    case 3:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("yellow" )); break;
                    case 4:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("black"  )); break;
   
                    default: r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;
                    }
                }
            else if (app.activeDocument.mode == DocumentMode.GRAYSCALE)
                {
                switch (n)
                    {
                    case -1: 
                    case 0:  r.putEnumerated(stringIDToTypeID("channel"),  stringIDToTypeID("channel"), stringIDToTypeID("black")); break;
   
                    default: r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;
                    }
                }

            else { alert("Unsupported color mode", "Error", true); return null; }
            }

        var ret;

        try { ret = executeActionGet(r).getList(stringIDToTypeID("histogram")); } catch (e) { alert(e); return null; }

        var hist = new Array();
        for (var i = 0; i < 256; i++) hist.push(ret.getInteger(i));

        return hist;
        }
    catch (e) { alert(e); return null; }
    }

 

 

 

 

3 replies

r-binCorrect answer
Brainiac
June 14, 2021

function get_average_color(color)

 

from here: Auto picking the most distinct accent color from an image

 

UPD.

 

Короче. По ссылке - глючная реплика со старого форума, скрипты там все нерабочие.

Вот готовый скрипт.

 

 

 

get_average_color(app.foregroundColor);

////////////////////////////////////////////////////////////
function get_average_color(color, x, y)
    {
    try {
        if (x != undefined && y != undefined) app.activeDocument.selection.select([[x,y],[x+1,y],[x+1,y+1],[x,y+1]], SelectionType.REPLACE); 
        
        var chnl = 3;
        if (app.activeDocument.mode == DocumentMode.CMYK) chnl = 4;

        if (app.activeDocument.mode == DocumentMode.GRAYSCALE) chnl = 1;

        var lm = new Array();
        var px = new Array();

        for (var i = 0; i < chnl; i++)
            {
            var hst = get_histogram(i+1);
            var l = 0;
            var p = 0;

            if (!hst) { return false; }

            for (var n in hst) { l += hst[n] * n; p += hst[n]; }  

            hst = null;

            lm.push(l);
            px.push(p);
            }

        if (app.activeDocument.mode == DocumentMode.RGB)
            {
            var r =lm[0]/px[0]; 
            var g =lm[1]/px[1]; 
            var b =lm[2]/px[2];

            with (color.rgb) { red = Math.round(r); green = Math.round(g); blue = Math.round(b); };
            }
        else if (app.activeDocument.mode == DocumentMode.LAB)
            {
            var _l = lm[0]/px[0] * 100/255; 
            var _a = lm[1]/px[1] - 128; 
            var _b = lm[2]/px[2] - 128;

            with (color.lab) { l = Math.round(_l); a = Math.round(_a); b = Math.round(_b); };
            }
        else if (app.activeDocument.mode == DocumentMode.CMYK)
            {
            var c = 100 - lm[0]/px[0] * 100/255; 
            var m = 100 - lm[1]/px[1] * 100/255; 
            var y = 100 - lm[2]/px[2] * 100/255;
            var k = 100 - lm[3]/px[3] * 100/255;

            with (color.cmyk) { cyan = Math.round(c); magenta = Math.round(m); yellow = Math.round(y); black = Math.round(k); };
            }
        else if (app.activeDocument.mode == DocumentMode.GRAYSCALE)
            {
            var _l = 100 - lm[0]/px[0] * 100/255; 

            with (color.gray) { gray = Math.round(_l);  };
            }
        else { alert("Unsupported color mode", "Error", true); return false; }

        if (x != undefined && y != undefined) app.activeDocument.selection.deselect();

        return true;
        }
    catch (e) { alert(e); }
    }

////////////////////////////////////////////////////////////
function get_histogram(n)
    {
    try {
        var r = new ActionReference();
        r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("histogram"));

        if (typeof(n) == "string")
            r.putName(stringIDToTypeID("channel"), n);
        else
            {
            if (app.activeDocument.mode == DocumentMode.RGB)
                {
                switch (n)
                    {       
                    case -1: r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;

                    case 0:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("RGB"  )); break;
                    case 1:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("red"  )); break;
                    case 2:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("green")); break;
                    case 3:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("blue" )); break;
   
                    default: r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;
                    }
                }
            else if (app.activeDocument.mode == DocumentMode.LAB)
                {
                switch (n)
                    {
                    case -1: 
                    case 0:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("lab"      )); break;
                    case 1:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("lightness")); break;
                    case 2:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("a"        )); break;
                    case 3:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("b"        )); break;
   
                    default: r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;
                    }
                }
            else if (app.activeDocument.mode == DocumentMode.CMYK)
                {
                switch (n)
                    {
                    case -1: r.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;

                    case 0:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("CMYK"   )); break;
                    case 1:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("cyan"   )); break;
                    case 2:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("magenta")); break;
                    case 3:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("yellow" )); break;
                    case 4:  r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("black"  )); break;
   
                    default: r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;
                    }
                }
            else if (app.activeDocument.mode == DocumentMode.GRAYSCALE)
                {
                switch (n)
                    {
                    case -1: 
                    case 0:  r.putEnumerated(stringIDToTypeID("channel"),  stringIDToTypeID("channel"), stringIDToTypeID("black")); break;
   
                    default: r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); break;
                    }
                }

            else { alert("Unsupported color mode", "Error", true); return null; }
            }

        var ret;

        try { ret = executeActionGet(r).getList(stringIDToTypeID("histogram")); } catch (e) { alert(e); return null; }

        var hist = new Array();
        for (var i = 0; i < 256; i++) hist.push(ret.getInteger(i));

        return hist;
        }
    catch (e) { alert(e); return null; }
    }

 

 

 

 

JJMack
Community Expert
June 14, 2021

I do not think a without a click to set a color sampler to the pixel a script can.  What do you know about the shape layer? Do  you know where in the Layer stack the shape layers is and what kind of a fill layer the shape layer is?  A script can get the bounds of a shape layer. Get the Paths of a shape layer there can be many path item for various close path in the layer's vector mask that combine in various ways,  A shape layers combined path can be stroked on the path, outside the path or inside the path and the stroke can be wide,   So Pixels in the shape layer  can very in color if its not a solid fill shape  and  part of the fill can be overlaid with a stroke.  So you must know the fill is a solid color and where the  x,y of an untainted pixels in the shape is.

 

A script  need to coded with some logic the will get the pixel in the shape you want to sample.  Once the script knows the Pixel's x,y it could set a color sampler to get that pixel color.

 

A selection is quite like a shape how would you know which x,y pixel in the has the color you want to sample, 

JJMack
Participating Frequently
June 14, 2021

To answer your questions:

1. it won't be a shape, but a regular raster layer.
2. The action is performed with the active layer
3. The fill of the selected area will be solid

Also in the screenshots in the reply to Kukurykus you can see the whole process step by step how it should work with the image.

JJMack
Community Expert
June 14, 2021

I do not see any process there or even your layer stack.

 

I see what look to be a screen capture of a layer mask  a gray scale channel black white with gray soft edges.

 

A screen capture of a raster image layer with a quick mask overlay.

 

A screen capture of a raster image layer with no mask applied but there an active selection the is like the captured Layer Mask load as a selection.

 

I see no layer stack wih layer with thumnails for contents and mask or any steps documented. 

 

I see one thing a selection

 

 

JJMack
Kukurykus
Brainiac
June 14, 2021

Easy to do, but hard to imagine what you mean by pre-selected randomly shaped area in a document.

Participating Frequently
June 14, 2021

For example, the shape of the selection and the position could be like this.
There will be one color in this area. It must be obtained.

Kukurykus
Brainiac
June 14, 2021

So you have a mask on a layer, or how your document for these layers part is constructed?