Skip to main content
Inspiring
June 19, 2022
Answered

Is it possible use "Blur average" on multiple selections?

  • June 19, 2022
  • 8 replies
  • 2808 views

When I make a circular selection on an image and use the Blur>average filter I get a single average spot color as expected. If I make similar multiple selections they all show the same color (none of them produce the selected average colour). Is it possible to make multiple selections and get the averaged color of each selection?

This topic has been closed for replies.
Correct answer Chuck Uebele

Ok, here's a script that will create circles using the average filter.

To run the script, you need to have an open file with a image reference layer named "base." You can flatten the layers as the script runs. This will make the script run faster, but if you plan to do anything with the individual layers, like a layer effect, you shouldn't do this. You can run it several times to get different sized circles. But the more layers, the slower the script will run.

 

#target photoshop
app.preferences.rulerUnits = Units.PIXELS;
var doc = activeDocument;
var run = true;
var sizeNorm = 200;
var sizeJit = 0;
var locJit = 0;
var spacingX = 0;
var spacingY = 0;
var offsetX = 0;
var offsetY = 0;
var flattenLay = false;
var lay1
var lay2

var dlg = new Window('dialog','Create Circles of Average Blur');
    dlg.sizeGp = dlg.add('panel',undefined,'Size');
        dlg.sizeGp.orientation = 'row';
        dlg.sizeGp.alignment = ['fill','top'];
        dlg.sizeGp.sizeNormStxt = dlg.sizeGp.add('statictext',undefined,'Circle size (pixels):');
        var sizeNormEtxt = dlg.sizeGp.add('edittext',undefined,sizeNorm);
            sizeNormEtxt.size = [70,17];
        dlg.sizeGp.sizeJitStxt = dlg.sizeGp.add('statictext',undefined,'Percent Jitter Size (50 = 50% - 25% larger and 25% smaller); 0 = no jitter:');
        var sizeJitEtxt = dlg.sizeGp.add('edittext',undefined,sizeJit);
            sizeJitEtxt.size = [70,17];
    dlg.locGp = dlg.add('panel',undefined,'Location');
        dlg.locGp.orientation = 'column';    
        dlg.locGp.alignment = ['fill','top'];    
        dlg.locGp.offGp = dlg.locGp.add('panel',undefined,'Offset in percent of size (0=No offset)');
            dlg.locGp.offGp.orientation = 'row';       
            dlg.locGp.offGp.alignment = ['fill','top'];   
            dlg.locGp.offGp.spaceXStxt = dlg.locGp.offGp.add('statictext',undefined,'X offset:');
            var offsetXEtxt = dlg.locGp.offGp.add('edittext',undefined,offsetX);
            offsetXEtxt.size = [70,17];
            dlg.locGp.offGp.spaceYStxt = dlg.locGp.offGp.add('statictext',undefined,'Y offset:');            
            var offsetYEtxt = dlg.locGp.offGp.add('edittext',undefined,offsetY);
            offsetYEtxt.size = [70,17]; 
        dlg.locGp.spaceGp = dlg.locGp.add('panel',undefined,'Spacing in percent of size (0=No offset; neg numbers for smaller space)');
            dlg.locGp.spaceGp.orientation = 'row';       
            dlg.locGp.spaceGp.alignment = ['fill','top'];  
            dlg.locGp.spaceGp.spacingXStxt = dlg.locGp.spaceGp.add('statictext',undefined,'X spacing:');
            var spacingXEtxt = dlg.locGp.spaceGp.add('edittext',undefined,spacingX);
            spacingXEtxt.size = [70,17];     
            dlg.locGp.spaceGp.spacingYStxt = dlg.locGp.spaceGp.add('statictext',undefined,'Y spacing:');
            var spacingYEtxt = dlg.locGp.spaceGp.add('edittext',undefined,spacingY);
            spacingYEtxt.size = [70,17];  
        dlg.locGp.locJitGp = dlg.locGp.add('panel',undefined,'Location jitter in percent of size (0=No offset)');
            dlg.locGp.locJitGp.orientation = 'row';       
            dlg.locGp.locJitGp.alignment = ['fill','top'];  
            dlg.locGp.locJitGp.locJitStxt = dlg.locGp.locJitGp.add('statictext',undefined,'Location Jitter:');
            var locJitEtxt = dlg.locGp.locJitGp.add('edittext',undefined,locJit);
            locJitEtxt.size = [70,17]; 
    dlg.flattenGp = dlg.add('panel',undefined,'Flatten');
        dlg.flattenGp.orientation = 'row';
        dlg.flattenGp.alignment = ['fill','top'];  
        var flattenLayChBx = dlg.flattenGp.add('checkbox', undefined,'Flatten Layers to speed up script');
    dlg.btnGp = dlg.add('group');
        dlg.btnGp.orientation = 'row';
        dlg.btnGp.orientChildren = ['center','top'];
        dlg.btnGp.ok = dlg.btnGp.add('button',undefined,'Okay');
        dlg.btnGp.cancel = dlg.btnGp.add('button',undefined,'Cancel');

         dlg.btnGp.ok.onClick = function(){
            dlg.close();
            sizeNorm = parseFloat(sizeNormEtxt.text);
            sizeJit = parseFloat(sizeJitEtxt.text);
            locJit = parseFloat(locJitEtxt.text);
            spacingX = parseFloat(spacingXEtxt.text);
            spacingY = parseFloat(spacingYEtxt.text);
            offsetX = parseFloat(offsetXEtxt.text);
            offsetY = parseFloat(offsetYEtxt.text); 
            flattenLay = flattenLayChBx.value;
            run = true;
            }
       
        dlg.btnGp.cancel.onClick = function(){
            run = false;
            dlg.close();
            }
            
dlg.show();
try{
    var base = doc.layers.getByName('base');
    }
catch (e){
    run = false;
    alert('A reference layer needs to be named "base."\n{all lowercase}');
    }
if (run){
    var stepY = sizeNorm + (sizeNorm*spacingY);
    var stepX = sizeNorm + (sizeNorm*spacingX);
    for(i=0+ (sizeNorm *offsetY);i-sizeNorm<doc.height;i+= stepY){
        for(j=0+ (sizeNorm *offsetX);j-sizeNorm<doc.width;j+= stepX){
            doc.activeLayer = base;
            var sizeUse = Math.random() *(sizeJit*sizeNorm) + sizeNorm - (sizeNorm*sizeJit)/2;
            var locUseX = Math.random() *(locJit*sizeNorm) + j - (sizeNorm*locJit)/2
            var locUseY = Math.random() *(locJit*sizeNorm) + i - (sizeNorm*locJit)/2

            createAvg (locUseX, locUseY, sizeUse/2)

            }//end j loop
        }//end i loop
    //createAvg (300, 200, 100/2)

    
    }

function createAvg(selCenterX, selCenterY,selSize){
    //================make selection
    var idsetd = charIDToTypeID( "setd" );
        var desc32 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref3 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idfsel = charIDToTypeID( "fsel" );
            ref3.putProperty( idChnl, idfsel );
        desc32.putReference( idnull, ref3 );
        var idT = charIDToTypeID( "T   " );
            var desc33 = new ActionDescriptor();
            var idTop = charIDToTypeID( "Top " );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc33.putUnitDouble( idTop, idPxl, selCenterY - selSize );
            var idLeft = charIDToTypeID( "Left" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc33.putUnitDouble( idLeft, idPxl, selCenterX - selSize );
            var idBtom = charIDToTypeID( "Btom" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc33.putUnitDouble( idBtom, idPxl, selCenterY + selSize );
            var idRght = charIDToTypeID( "Rght" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc33.putUnitDouble( idRght, idPxl, selCenterX + selSize );
        var idElps = charIDToTypeID( "Elps" );
        desc32.putObject( idT, idElps, desc33 );
        var idAntA = charIDToTypeID( "AntA" );
        desc32.putBoolean( idAntA, true );
    executeAction( idsetd, desc32, DialogModes.NO );
    //check to see if a selection was made and not outside of canvas area
    try{
        var test = doc.selection.bounds
        }
    catch(e){
        return
        }
    //================== duplicate layer
    try{
        var idCpTL = charIDToTypeID( "CpTL" );
            executeAction( idCpTL, undefined, DialogModes.NO );
        }
    catch(e){return}
    
    //=========== make selection from layer
    var idsetd = charIDToTypeID( "setd" );
        var desc37 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref4 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idfsel = charIDToTypeID( "fsel" );
            ref4.putProperty( idChnl, idfsel );
        desc37.putReference( idnull, ref4 );
        var idT = charIDToTypeID( "T   " );
            var ref5 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idChnl = charIDToTypeID( "Chnl" );
            var idTrsp = charIDToTypeID( "Trsp" );
            ref5.putEnumerated( idChnl, idChnl, idTrsp );
        desc37.putReference( idT, ref5 );
    executeAction( idsetd, desc37, DialogModes.NO );
    
    //========Average
    var idAvrg = charIDToTypeID( "Avrg" );
    executeAction( idAvrg, undefined, DialogModes.NO );    
    
    //==========deselect
    var idsetd = charIDToTypeID( "setd" );
        var desc44 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref6 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idfsel = charIDToTypeID( "fsel" );
            ref6.putProperty( idChnl, idfsel );
        desc44.putReference( idnull, ref6 );
        var idT = charIDToTypeID( "T   " );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idNone = charIDToTypeID( "None" );
        desc44.putEnumerated( idT, idOrdn, idNone );
    executeAction( idsetd, desc44, DialogModes.NO );    
    
    //===============flatten
    if(flattenLay){
         if(lay1== null){lay1 = doc.activeLayer}
         else{
             lay2 = doc.activeLayer;
             doc.activeLayer = lay1;
             
            var idMrgtwo = charIDToTypeID( "Mrg2" );
                var desc5 = new ActionDescriptor();
            executeAction( idMrgtwo, desc5, DialogModes.NO );     
            
            lay1 = doc.activeLayer;
            lay2 = null;
             }
        }
    }

8 replies

rayek.elfin
Legend
June 24, 2022

As an alternative, consider the Op Art filter in G'MIC. The Op Art filter is very configurable and processes fast (a second or so on a typical 3648x5472 photo). Doesn't output separate layers for each dot, though. But allows for much more control and additional effects such as varying size of the circles based on luminance, different shapes (hearts, arrows, boxes, etc.).

 

Also includes many other interesting filters and effects. Best of all: the plugin is open source and free! 

Download and more info here: https://gmic.eu/

 

Regular Op Art circles:

With varying circle size (minimum and maximum sizes are configurable)

"3d" lighted balls:

   

Bee__JayAuthor
Inspiring
June 25, 2022

@rayek.elfin, The Op Art filter looks interesting and thank you for the link. I could not find the Op Art filter. Do you have a direct link to it?

rayek.elfin
Legend
June 26, 2022

@Bee__Jay  the Op Art filter is part of the G'MIC plugin. Install the G'MIC plugin as you would any other 8bf file (in your plugins folder) and restart Photoshop. Then open an image, and start G'MIC. Search for Op Art in the search field, and play with the settings. To create spheres ensure "invert" is changed from its default setting.

Chuck Uebele
Community Expert
Chuck UebeleCommunity ExpertCorrect answer
Community Expert
June 23, 2022

Ok, here's a script that will create circles using the average filter.

To run the script, you need to have an open file with a image reference layer named "base." You can flatten the layers as the script runs. This will make the script run faster, but if you plan to do anything with the individual layers, like a layer effect, you shouldn't do this. You can run it several times to get different sized circles. But the more layers, the slower the script will run.

 

#target photoshop
app.preferences.rulerUnits = Units.PIXELS;
var doc = activeDocument;
var run = true;
var sizeNorm = 200;
var sizeJit = 0;
var locJit = 0;
var spacingX = 0;
var spacingY = 0;
var offsetX = 0;
var offsetY = 0;
var flattenLay = false;
var lay1
var lay2

var dlg = new Window('dialog','Create Circles of Average Blur');
    dlg.sizeGp = dlg.add('panel',undefined,'Size');
        dlg.sizeGp.orientation = 'row';
        dlg.sizeGp.alignment = ['fill','top'];
        dlg.sizeGp.sizeNormStxt = dlg.sizeGp.add('statictext',undefined,'Circle size (pixels):');
        var sizeNormEtxt = dlg.sizeGp.add('edittext',undefined,sizeNorm);
            sizeNormEtxt.size = [70,17];
        dlg.sizeGp.sizeJitStxt = dlg.sizeGp.add('statictext',undefined,'Percent Jitter Size (50 = 50% - 25% larger and 25% smaller); 0 = no jitter:');
        var sizeJitEtxt = dlg.sizeGp.add('edittext',undefined,sizeJit);
            sizeJitEtxt.size = [70,17];
    dlg.locGp = dlg.add('panel',undefined,'Location');
        dlg.locGp.orientation = 'column';    
        dlg.locGp.alignment = ['fill','top'];    
        dlg.locGp.offGp = dlg.locGp.add('panel',undefined,'Offset in percent of size (0=No offset)');
            dlg.locGp.offGp.orientation = 'row';       
            dlg.locGp.offGp.alignment = ['fill','top'];   
            dlg.locGp.offGp.spaceXStxt = dlg.locGp.offGp.add('statictext',undefined,'X offset:');
            var offsetXEtxt = dlg.locGp.offGp.add('edittext',undefined,offsetX);
            offsetXEtxt.size = [70,17];
            dlg.locGp.offGp.spaceYStxt = dlg.locGp.offGp.add('statictext',undefined,'Y offset:');            
            var offsetYEtxt = dlg.locGp.offGp.add('edittext',undefined,offsetY);
            offsetYEtxt.size = [70,17]; 
        dlg.locGp.spaceGp = dlg.locGp.add('panel',undefined,'Spacing in percent of size (0=No offset; neg numbers for smaller space)');
            dlg.locGp.spaceGp.orientation = 'row';       
            dlg.locGp.spaceGp.alignment = ['fill','top'];  
            dlg.locGp.spaceGp.spacingXStxt = dlg.locGp.spaceGp.add('statictext',undefined,'X spacing:');
            var spacingXEtxt = dlg.locGp.spaceGp.add('edittext',undefined,spacingX);
            spacingXEtxt.size = [70,17];     
            dlg.locGp.spaceGp.spacingYStxt = dlg.locGp.spaceGp.add('statictext',undefined,'Y spacing:');
            var spacingYEtxt = dlg.locGp.spaceGp.add('edittext',undefined,spacingY);
            spacingYEtxt.size = [70,17];  
        dlg.locGp.locJitGp = dlg.locGp.add('panel',undefined,'Location jitter in percent of size (0=No offset)');
            dlg.locGp.locJitGp.orientation = 'row';       
            dlg.locGp.locJitGp.alignment = ['fill','top'];  
            dlg.locGp.locJitGp.locJitStxt = dlg.locGp.locJitGp.add('statictext',undefined,'Location Jitter:');
            var locJitEtxt = dlg.locGp.locJitGp.add('edittext',undefined,locJit);
            locJitEtxt.size = [70,17]; 
    dlg.flattenGp = dlg.add('panel',undefined,'Flatten');
        dlg.flattenGp.orientation = 'row';
        dlg.flattenGp.alignment = ['fill','top'];  
        var flattenLayChBx = dlg.flattenGp.add('checkbox', undefined,'Flatten Layers to speed up script');
    dlg.btnGp = dlg.add('group');
        dlg.btnGp.orientation = 'row';
        dlg.btnGp.orientChildren = ['center','top'];
        dlg.btnGp.ok = dlg.btnGp.add('button',undefined,'Okay');
        dlg.btnGp.cancel = dlg.btnGp.add('button',undefined,'Cancel');

         dlg.btnGp.ok.onClick = function(){
            dlg.close();
            sizeNorm = parseFloat(sizeNormEtxt.text);
            sizeJit = parseFloat(sizeJitEtxt.text);
            locJit = parseFloat(locJitEtxt.text);
            spacingX = parseFloat(spacingXEtxt.text);
            spacingY = parseFloat(spacingYEtxt.text);
            offsetX = parseFloat(offsetXEtxt.text);
            offsetY = parseFloat(offsetYEtxt.text); 
            flattenLay = flattenLayChBx.value;
            run = true;
            }
       
        dlg.btnGp.cancel.onClick = function(){
            run = false;
            dlg.close();
            }
            
dlg.show();
try{
    var base = doc.layers.getByName('base');
    }
catch (e){
    run = false;
    alert('A reference layer needs to be named "base."\n{all lowercase}');
    }
if (run){
    var stepY = sizeNorm + (sizeNorm*spacingY);
    var stepX = sizeNorm + (sizeNorm*spacingX);
    for(i=0+ (sizeNorm *offsetY);i-sizeNorm<doc.height;i+= stepY){
        for(j=0+ (sizeNorm *offsetX);j-sizeNorm<doc.width;j+= stepX){
            doc.activeLayer = base;
            var sizeUse = Math.random() *(sizeJit*sizeNorm) + sizeNorm - (sizeNorm*sizeJit)/2;
            var locUseX = Math.random() *(locJit*sizeNorm) + j - (sizeNorm*locJit)/2
            var locUseY = Math.random() *(locJit*sizeNorm) + i - (sizeNorm*locJit)/2

            createAvg (locUseX, locUseY, sizeUse/2)

            }//end j loop
        }//end i loop
    //createAvg (300, 200, 100/2)

    
    }

function createAvg(selCenterX, selCenterY,selSize){
    //================make selection
    var idsetd = charIDToTypeID( "setd" );
        var desc32 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref3 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idfsel = charIDToTypeID( "fsel" );
            ref3.putProperty( idChnl, idfsel );
        desc32.putReference( idnull, ref3 );
        var idT = charIDToTypeID( "T   " );
            var desc33 = new ActionDescriptor();
            var idTop = charIDToTypeID( "Top " );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc33.putUnitDouble( idTop, idPxl, selCenterY - selSize );
            var idLeft = charIDToTypeID( "Left" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc33.putUnitDouble( idLeft, idPxl, selCenterX - selSize );
            var idBtom = charIDToTypeID( "Btom" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc33.putUnitDouble( idBtom, idPxl, selCenterY + selSize );
            var idRght = charIDToTypeID( "Rght" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc33.putUnitDouble( idRght, idPxl, selCenterX + selSize );
        var idElps = charIDToTypeID( "Elps" );
        desc32.putObject( idT, idElps, desc33 );
        var idAntA = charIDToTypeID( "AntA" );
        desc32.putBoolean( idAntA, true );
    executeAction( idsetd, desc32, DialogModes.NO );
    //check to see if a selection was made and not outside of canvas area
    try{
        var test = doc.selection.bounds
        }
    catch(e){
        return
        }
    //================== duplicate layer
    try{
        var idCpTL = charIDToTypeID( "CpTL" );
            executeAction( idCpTL, undefined, DialogModes.NO );
        }
    catch(e){return}
    
    //=========== make selection from layer
    var idsetd = charIDToTypeID( "setd" );
        var desc37 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref4 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idfsel = charIDToTypeID( "fsel" );
            ref4.putProperty( idChnl, idfsel );
        desc37.putReference( idnull, ref4 );
        var idT = charIDToTypeID( "T   " );
            var ref5 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idChnl = charIDToTypeID( "Chnl" );
            var idTrsp = charIDToTypeID( "Trsp" );
            ref5.putEnumerated( idChnl, idChnl, idTrsp );
        desc37.putReference( idT, ref5 );
    executeAction( idsetd, desc37, DialogModes.NO );
    
    //========Average
    var idAvrg = charIDToTypeID( "Avrg" );
    executeAction( idAvrg, undefined, DialogModes.NO );    
    
    //==========deselect
    var idsetd = charIDToTypeID( "setd" );
        var desc44 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref6 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idfsel = charIDToTypeID( "fsel" );
            ref6.putProperty( idChnl, idfsel );
        desc44.putReference( idnull, ref6 );
        var idT = charIDToTypeID( "T   " );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idNone = charIDToTypeID( "None" );
        desc44.putEnumerated( idT, idOrdn, idNone );
    executeAction( idsetd, desc44, DialogModes.NO );    
    
    //===============flatten
    if(flattenLay){
         if(lay1== null){lay1 = doc.activeLayer}
         else{
             lay2 = doc.activeLayer;
             doc.activeLayer = lay1;
             
            var idMrgtwo = charIDToTypeID( "Mrg2" );
                var desc5 = new ActionDescriptor();
            executeAction( idMrgtwo, desc5, DialogModes.NO );     
            
            lay1 = doc.activeLayer;
            lay2 = null;
             }
        }
    }
Chuck Uebele
Community Expert
Community Expert
June 23, 2022

Here is a test, with the original layer, a fill layer with same sized circles overlapping by 50% and a random location and size layer, with smaller circles.

Bee__JayAuthor
Inspiring
June 23, 2022

Wow!!! Thank you very much indeed. I never dreamed that I would get this much help with my question.

I now have two questions:

• How do I install the script?

• Am I correct in assuming all those initial variables can be set prior to running the main script?  

Bojan Živković11378569
Community Expert
Community Expert
June 20, 2022

Maybe @c.pfaffenbichler @r-bin @jazz-y @Kukurykus @Stephen Marsh can help something?

Bee__JayAuthor
Inspiring
June 19, 2022

Thank you Barbara Ash, Signfeld and Chuck Uebele for taking the time to answer my question. You all confirmed that it could only be achieved with a script and saved me a lot of experimental time. I have been trying the clone stamp tool without success.  I am an occasional user of photoshop, not familiar with scripting and a little too old to learn a new language. I have a lot of hobbies but my real passion is art. I use PS to prepare images that I paint on canvas. A long time ago I built a very succesful machine that painted pictures on canvas with thick blobs of custom oil paint. In recent years I made manual blobbers that deposit thick oil paint with results similar to my machine but allows me to paint much larger pictures. If anyone is interested I would be happy to post a link to my paintings. Chuck's example in this thread is almost exactly what I am trying to achieve.

Thank you all again for your help.

Barrie

Zesty_wanderlust15A7
Known Participant
June 19, 2022

I think your idea is good for the example use I gave, so I'm interested to try and script it for my use, which may help you.

Furthermore, Chuck may have this script kind of ready-to-go and share a modification too, as you seem likeminded souls 🙂

I don't know how many selections PS can handle in one go, but for your use you can run it as many times as you want.

Bee__JayAuthor
Inspiring
June 19, 2022

Wow! I really didn't expect such direct help. Thank you for your interest.

I have tried a few commercial plugins and scripts for creating pointillist art but none have matched my vision. I could outline the features of what I think is an ideal process and if necessary you could modify to suite the available script. Is it OK to discuss the details here or is it more appropriate to do it by email? 

Chuck Uebele
Community Expert
Community Expert
June 19, 2022

As mentioned, you need separate selections to do that, but a script could automate the process. This was a script that I did that made random ovals and applied a gradient to them, from a reference image. The ovals could have just as easily been filled using the average filter.

 

jane-e
Community Expert
Community Expert
June 19, 2022

That's a cool self-portrait Chuck!

 

Jane

 

Zesty_wanderlust15A7
Known Participant
June 19, 2022

Without a script, something clever might be possible as well, especially if you would use the same amount of selections every time and (maybe) have layers named a certain way.

A way you might start the action is to jump the selections to a new layer. Right-click that layer and select Mask All Objects. From here, I'm sure you can get there.

To make it somewhat dynamic for an amount of selections, you might be able to get away with just a small helper script. For example, you could go up a layer and each time have the layer name checked by the script, then call a helper subaction if it is still one of these masks. Well... something like that.

Zesty_wanderlust15A7
Known Participant
June 19, 2022

Working action (within limits) for three selections:

https://www98.zippyshare.com/v/YF1rwL4B/file.html

I'm seeing that a marquee selection can get ignored by the object finder, so prefer lasso selections.

The object finder may have other limitations, like maybe small selections, etc. A healthy blob seems to work well 🙂

Upd.: indeed, small selections don't get recognized 😞  So a script will be better after all...

Turning the jumped layer selections black is helping!

After the selections are jumped to a new layer add the step:
Edit > Fill (Black; Preserve Transparency)

Zesty_wanderlust15A7
Known Participant
June 19, 2022

Added some notes above  ^

A cool use of the action is to make selections where skin retouch is needed. Add a black mask over the final layer and paint in on just one single layer 🙂

Drawback of not using separate masked color or solid fill layers is that your selection has to cover everything where you might paint, including sections of skin you might not want to include for averaging but would want to paint in...
For this use and to save space you could also delete the pixels that are not the averaged patches somewhere in the action. You could also grow the patches a little to cover more territory under your mask, as long as they don't spill over into critical territory of another patch.

Zesty_wanderlust15A7
Known Participant
June 19, 2022

You want this with the click of a button?

I think a script might be able to loop through each selection and make that work, but it surpasses my 5-line scripting expertise... 😉

 

barbara_a7746676
Community Expert
Community Expert
June 19, 2022

As you discovered, if you have multiple selections, they will all be averaged to the same color.

You'll need to make the selections and average them one at a time.

To speed up the process, you could use a keyboard shortcut or create an action.