• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Scripting radial cutout's

Explorer ,
Jan 05, 2022 Jan 05, 2022

Copy link to clipboard

Copied

so i have a ton of images.

I have to apply a radial marquee and cut out the exterior excess.

Below is an example of what i have to do:

 

 

obama-original.jpgobama-radial-cutout.pngdiagram-radial.gif

So i want to automate this, I will have images of all different shapes and sizes so i would want to be able to pick the size of the radial programatically.

Above you will see my colored diagram. i would always want my radial to start from the center but i would like to be able to choose the width (blue highlight) and height (red highlight) of the radial (green highlight).  I would need something relative such as a percentage.  it doesnt really matter at this point, i could work with pixels if need be.. as long as i am able to programmatically adjust the width and height.

 

Would anyone know how i can start doing this? 

TOPICS
Actions and scripting , SDK

Views

290

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Guide ,
Jan 06, 2022 Jan 06, 2022

Copy link to clipboard

Copied

 

#target photoshop

var selWidth = 70, //percents
    selHeight = 90, //percents
    doc = new AM('document'),
    res = doc.getProperty('resolution'),
    docWidth = doc.getProperty('width') * res / 72,
    docHeight = doc.getProperty('height') * res / 72;

doc.makeEllipseSelection(
    (docHeight - docHeight * selHeight / 100) / 2,
    (docWidth - docWidth * selWidth / 100) / 2,
    docHeight - (docHeight - docHeight * selHeight / 100) / 2,
    docWidth - (docWidth - docWidth * selWidth / 100) / 2,
    true
)

function AM(target) {
    var s2t = stringIDToTypeID,
        t2s = typeIDToStringID;

    target = target ? s2t(target) : null;

    this.getProperty = function (property, id, idxMode) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id != undefined ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id)) :
            r.putEnumerated(target, s2t('ordinal'), s2t('targetEnum'));
        return getDescValue(executeActionGet(r), property)
    }

    this.hasProperty = function (property, id, idxMode) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id))
            : r.putEnumerated(target, s2t('ordinal'), s2t('targetEnum'));
        try { return executeActionGet(r).hasKey(property) } catch (e) { return false }
    }

    this.descToObject = function (d) {
        var o = {}
        for (var i = 0; i < d.count; i++) {
            var k = d.getKey(i)
            o[t2s(k)] = getDescValue(d, k)
        }
        return o
    }

    this.makeEllipseSelection = function (top, left, bottom, right, AntA) {
        (r = new ActionReference()).putProperty(s2t('channel'), s2t('selection'));
        (d = new ActionDescriptor()).putReference(s2t('target'), r);
        (d1 = new ActionDescriptor()).putUnitDouble(s2t('top'), s2t('pixelsUnit'), top);
        d1.putUnitDouble(s2t('left'), s2t('pixelsUnit'), left);
        d1.putUnitDouble(s2t('bottom'), s2t('pixelsUnit'), bottom);
        d1.putUnitDouble(s2t('right'), s2t('pixelsUnit'), right);
        d.putObject(s2t('to'), s2t('ellipse'), d1);
        d.putBoolean(s2t('antiAlias'), AntA);
        executeAction(s2t('set'), d, DialogModes.NO);

    }
    function getDescValue(d, k) {
        switch (d.getType(k)) {
            case DescValueType.OBJECTTYPE: return { type: t2s(d.getObjectType(k)), value: d.getObjectValue(k) };
            case DescValueType.LISTTYPE: return d.getList(k);
            case DescValueType.REFERENCETYPE: return d.getReference(k);
            case DescValueType.BOOLEANTYPE: return d.getBoolean(k);
            case DescValueType.STRINGTYPE: return d.getString(k);
            case DescValueType.INTEGERTYPE: return d.getInteger(k);
            case DescValueType.LARGEINTEGERTYPE: return d.getLargeInteger(k);
            case DescValueType.DOUBLETYPE: return d.getDouble(k);
            case DescValueType.ALIASTYPE: return d.getPath(k);
            case DescValueType.CLASSTYPE: return d.getClass(k);
            case DescValueType.UNITDOUBLE: return (d.getUnitDoubleValue(k));
            case DescValueType.ENUMERATEDTYPE: return { type: t2s(d.getEnumerationType(k)), value: t2s(d.getEnumerationValue(k)) };
            default: break;
        };
    }
}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 09, 2022 Jan 09, 2022

Copy link to clipboard

Copied

@davidc88034496 - how did you go with the script from jazz-y?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jan 09, 2022 Jan 09, 2022

Copy link to clipboard

Copied

So i still have to test it out.  Im currently rushing through a ton of other things i have on my plate.  Im going to give the script a try once i cross that road here on my end.  I feel confident it will work though.  I thought perhaps there would be an object oriented way of doing it rather than the ActionScript way but hey.. it is what it is.. hopefully ill get to it sometime this week.  but im definitely going to need this script

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 09, 2022 Jan 09, 2022

Copy link to clipboard

Copied


@davidc88034496 wrote:

So i still have to test it out.  Im currently rushing through a ton of other things i have on my plate.  Im going to give the script a try once i cross that road here on my end.  I feel confident it will work though. 


 

Fair enough, we have a lot of "hit and run" posts, somebody asks for help, help is provided, then there is no reply.

 

 


@davidc88034496 wrote:

I thought perhaps there would be an object oriented way of doing it rather than the ActionScript way but hey.. it is what it is.. hopefully ill get to it sometime this week.  but im definitely going to need this script


 

What exactly do you mean by "object oriented"? It can also be semi-automated using an action, rather than a script (in Photoshop, Actions and Scripts are two separate things, there is no ActionScript). The script from jazz-y was fully automated, this action approach is sem-automated. You have only provided a single image example, which was a tight/close crop which is easy to make into an eliptical shape from the canvas area. But what if the image is not nicely framed?

 

Here is an interactive action to create a vector layer mask. The mask is transformed during action playback to get the size and position correct. If you later change your mind, it can later be adjusted by transforming the path again, retaining the path object and vector mask properties for a "live" crop:

 

interactive.png

 

final.png

 

The script was recorded using arbitrary values that resulted in a 3.5:5 ratio, but this could be changed if you always wanted to start at a ratio of say 5:7 or 4:5 (8:10) etc.

 

Download link to action:

https://www.dropbox.com/s/71l6kqsjn2wocc5/Interactive%20Eliptical%20Vector%20Mask.atn?dl=0

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 09, 2022 Jan 09, 2022

Copy link to clipboard

Copied


@davidc88034496 wrote:

So i want to automate this, I will have images of all different shapes and sizes so i would want to be able to pick the size of the radial programatically.

 

We have had scripting topics where a script leverages the facial recognition of the liquify command to automatically get an approximation of the face area, then an eliptical crop could be centred around that area etc...

 

Edit: Some links for later reference...

 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-crop-from-face-detection/m-p/11...

 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/crop-trim-image-automation-3-4/m-p/12...

https://community.adobe.com/t5/photoshop-ecosystem-discussions/get-the-facial-features-from-liquify-...

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jan 09, 2022 Jan 09, 2022

Copy link to clipboard

Copied

so what i mean by object oriented manner... 
I was hoping there was an "object" already crafted by Adobe .. so for example.

 

var EclipseMarquee = New EclipseMarquee();

EclipseMarquee.Draw(x, y, width, height);

EclipseMarquee.MakeSelection();

EclipseMarquee.InvertSelection();

EclipseMarquee.Cut();

 

Where i can simply script the top and the job would be done.  (The above is just a fake example) but i hope you get the idea.

 

I personally dont like the "ActionReference" code.  I am not sure what its called exactly but if you look at Jazz-y code, he has that "function AM(target)" code with all that generated code.  Im more use to Adobe XD where there is a ton of "objects" already created for you and you can do virtually anything by calling "objects" and methods that do the same thing you get with the GUI of Adobe XD. 

 

but regardless, if it works it works so im grateful!

Using that liquify command seems like something i might need because yes, with all these images, they are of many different shapes and sizes.  Usually they would have one subject. such as a model or person and we would want to create a gradient cut out around them.

Just please do bare with me though as i am still busy but i will have to start working on finding a solutiont to "radial cut-out" multiple pictures soon.  So just give me a few days and ima come back to see what i can find.  This is definitely something big and we would like to tackle it.  Thanks so much!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 09, 2022 Jan 09, 2022

Copy link to clipboard

Copied

LATEST

@davidc88034496 wrote:

so what i mean by object oriented manner... 
I was hoping there was an "object" already crafted by Adobe .. so for example.

 

var EclipseMarquee = New EclipseMarquee();

EclipseMarquee.Draw(x, y, width, height);

 

It is "easy enough" to create one using Action Manager code recorded by the Scripting Listener plug-in, wrapping it into a function with variables for the top/left/bottom/right values and then passing in parameters for these values when calling the function. The parameters are hard-coded, but simple prompts or a GUI could be created for live input, but that of course takes more work. Then you would add in other bits of code to perform the rest of the operation.

 

ellipticalSelectAll(0, 0, app.activeDocument.height.value, app.activeDocument.width.value, true);

function ellipticalSelectAll(top, left, bottom, right, antiAlias) {
	var s2t = function (s) {
		return app.stringIDToTypeID(s);
	};
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var reference = new ActionReference();
	reference.putProperty( s2t( "channel" ), s2t( "selection" ));
	descriptor.putReference( s2t( "null" ), reference );
	descriptor2.putUnitDouble( s2t( "top" ), s2t( "pixelsUnit" ), top );
	descriptor2.putUnitDouble( s2t( "left" ), s2t( "pixelsUnit" ), left );
	descriptor2.putUnitDouble( s2t( "bottom" ), s2t( "pixelsUnit" ), bottom );
	descriptor2.putUnitDouble( s2t( "right" ), s2t( "pixelsUnit" ), right );
	descriptor.putObject( s2t( "to" ), s2t( "ellipse" ), descriptor2 );
	descriptor.putBoolean( s2t( "antiAlias" ), antiAlias );
	executeAction( s2t( "set" ), descriptor, DialogModes.NO );
}

 

https://gist.github.com/MarshySwamp/451f60096079084b818d693d8cf09547

 

You can combine such "helper scripts" as above into an action, where the script does what you can't do via an action but the action performs the bits that you can do. This is generally the best approach if you can't script or don't want/need to script.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines