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

Programmatically convert shape layer to masked color fill layer

Participant ,
Apr 05, 2024 Apr 05, 2024

Copy link to clipboard

Copied

I'm looking for a scripting or actions wizard—

 

I have an illustration workflow that involves making a drawing in Illustrator and then pasting into Photoshop as many different shape layers. Then I convert these shape layers into masked color fill layers. The whole point of this workflow is being able to use Photoshop filters on the masks to rough up the edges of the shape. This workflow works great for me.  

 

BUT the process of manually converting each shape layer into a masked color fill layer is a little tedious. What's tricky is that the color fill layer needs to retain the color of the shape layer.

 

I can use shortcuts and actions to speed this up a little, but it quickly gets unwieldy if I have more than a few dozen layers.

 

Surely there's some way to automate this?

 

Here's a screencapture of me doing it manually:

1.gif

TOPICS
Actions and scripting , macOS

Views

778

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

correct answers 2 Correct answers

People's Champ , Apr 05, 2024 Apr 05, 2024
Logically, you want to convert the vector mask to a regular one. Try this script for the active shape layer.
 

 

 

try {

// vector masrk to selection (antialias, feather 0)

var d = new ActionDescriptor();  
var r = new ActionReference();  
r.putProperty(stringIDToTypeID("channel"), stringIDToTypeID("selection"));  
d.putReference(stringIDToTypeID("null"), r);  
var r1 = new ActionReference();  
r1.putEnumerated(stringIDToTypeID("path"), stringIDToTypeID("path"), stringIDToTypeID("vectorMask"));
r1
...

Votes

Translate

Translate
Community Expert , Apr 06, 2024 Apr 06, 2024

Not elegant, but I wonder whether existing Layer Masks may merit consideration.

Edited: updated to the code to exclude Shape Layers with Strokes

Screenshot 2024-04-06 at 13.27.34.pngScreenshot 2024-04-06 at 13.27.43.png

 

 

// change shape layer vector masks to layer masks;
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var theLayers = collectShapeLayers();
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// process layers;
for (var m = 0; m < theLayers.length; m++) {
// if layer has no stroke;
if (theL
...

Votes

Translate

Translate
Adobe
People's Champ ,
Apr 05, 2024 Apr 05, 2024

Copy link to clipboard

Copied

Logically, you want to convert the vector mask to a regular one. Try this script for the active shape layer.
 

 

 

try {

// vector masrk to selection (antialias, feather 0)

var d = new ActionDescriptor();  
var r = new ActionReference();  
r.putProperty(stringIDToTypeID("channel"), stringIDToTypeID("selection"));  
d.putReference(stringIDToTypeID("null"), r);  
var r1 = new ActionReference();  
r1.putEnumerated(stringIDToTypeID("path"), stringIDToTypeID("path"), stringIDToTypeID("vectorMask"));
r1.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("to"), r1);  
d.putBoolean(stringIDToTypeID("antiAlias"), true);  
d.putUnitDouble(stringIDToTypeID("feather"), stringIDToTypeID("pixelsUnit"), 0);  
executeAction(stringIDToTypeID("set"), d, DialogModes.NO);  


// create pixel mask from selection 

var d = new ActionDescriptor();
d.putClass(stringIDToTypeID("new"), stringIDToTypeID("channel"));
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("channel"), stringIDToTypeID("channel"), stringIDToTypeID("mask"));
d.putReference(stringIDToTypeID("at"), r);
d.putEnumerated(stringIDToTypeID("using"), stringIDToTypeID("userMaskOptions"), stringIDToTypeID("revealSelection"));
executeAction(stringIDToTypeID("make"), d, DialogModes.NO);


// delete current vector mask

var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("path"), stringIDToTypeID("path"), stringIDToTypeID("vectorMask"));
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("delete"), d, DialogModes.NO);


} catch (e) { alert(e.line+ "\n\n" +e); }

 

 

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
Participant ,
Apr 06, 2024 Apr 06, 2024

Copy link to clipboard

Copied

😍 Wow, amazing! This works perfectly. I literally gasped and laughed out loud. This will save me so much time! Thank you, kind internet stranger!

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 ,
Apr 06, 2024 Apr 06, 2024

Copy link to clipboard

Copied

Not elegant, but I wonder whether existing Layer Masks may merit consideration.

Edited: updated to the code to exclude Shape Layers with Strokes

Screenshot 2024-04-06 at 13.27.34.pngScreenshot 2024-04-06 at 13.27.43.png

 

 

// change shape layer vector masks to layer masks;
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var theLayers = collectShapeLayers();
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// process layers;
for (var m = 0; m < theLayers.length; m++) {
// if layer has no stroke;
if (theLayers[m][3] == false) {
selectLayerByID(theLayers[m][1], false);
// load as selection, apply as mask and delete vector mask;
var idchannel = stringIDToTypeID( "channel" );
var idpath = stringIDToTypeID( "path" );
var idnull = stringIDToTypeID( "null" );
var idvectorMask = stringIDToTypeID( "vectorMask" );
// =======================================================
    var desc5 = new ActionDescriptor();
        var ref1 = new ActionReference();
        ref1.putProperty( idchannel, stringIDToTypeID( "selection" ) );
    desc5.putReference( idnull, ref1 );
        var ref2 = new ActionReference();
        ref2.putEnumerated( idpath, idpath, idvectorMask );
        ref2.putEnumerated( stringIDToTypeID( "layer" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
    desc5.putReference( stringIDToTypeID( "to" ), ref2 );
    desc5.putInteger( stringIDToTypeID( "version" ), 1 );
    desc5.putBoolean( stringIDToTypeID( "vectorMaskParams" ), true );
executeAction( stringIDToTypeID( "set" ), desc5, DialogModes.NO );
if (theLayers[m][2] == false) {
    var desc7 = new ActionDescriptor();
    desc7.putClass( stringIDToTypeID( "new" ), idchannel );
        var ref3 = new ActionReference();
        var idmask = stringIDToTypeID( "mask" );
        ref3.putEnumerated( idchannel, idchannel, idmask );
    desc7.putReference( stringIDToTypeID( "at" ), ref3 );
    desc7.putEnumerated( stringIDToTypeID( "using" ), stringIDToTypeID( "userMaskEnabled" ), stringIDToTypeID( "revealSelection" ) );
executeAction( stringIDToTypeID( "make" ), desc7, DialogModes.NO );
} else {
    var desc10 = new ActionDescriptor();
        var ref6 = new ActionReference();
        ref6.putEnumerated( idchannel, idchannel, stringIDToTypeID( "mask" ) );
    desc10.putReference( stringIDToTypeID( "null" ), ref6 );
    var idmakeVisible = stringIDToTypeID( "makeVisible" );
    desc10.putBoolean( idmakeVisible, false );
executeAction( stringIDToTypeID( "select" ), desc10, DialogModes.NO );
// =======================================================
executeAction( stringIDToTypeID( "inverse" ), undefined, DialogModes.NO );
// =======================================================
    var desc18 = new ActionDescriptor();
        var ref8 = new ActionReference();
        ref8.putProperty( stringIDToTypeID( "color" ), stringIDToTypeID( "colors" ) );
    desc18.putReference( stringIDToTypeID( "null" ), ref8 );
executeAction( stringIDToTypeID( "reset" ), desc18, DialogModes.NO );
// =======================================================
    var desc5 = new ActionDescriptor();
        var ref2 = new ActionReference();
        ref2.putProperty( stringIDToTypeID( "color" ), stringIDToTypeID( "colors" ) );
    desc5.putReference( stringIDToTypeID( "null" ), ref2 );
executeAction( stringIDToTypeID( "exchange" ), desc5, DialogModes.NO );
// =======================================================
    var desc13 = new ActionDescriptor();
    desc13.putEnumerated( stringIDToTypeID( "using" ), stringIDToTypeID( "fillContents" ), stringIDToTypeID( "foregroundColor" ) );
    desc13.putUnitDouble( stringIDToTypeID( "opacity" ),stringIDToTypeID( "percentUnit" ), 100.000000 );
    desc13.putEnumerated( stringIDToTypeID( "mode" ), stringIDToTypeID( "blendMode" ), stringIDToTypeID( "normal" ) );
executeAction( stringIDToTypeID( "fill" ), desc13, DialogModes.NO );
};
// =======================================================
    var desc9 = new ActionDescriptor();
        var ref4 = new ActionReference();
        ref4.putEnumerated( idpath, idpath, idvectorMask );
        ref4.putEnumerated( stringIDToTypeID( "layer" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
    desc9.putReference( idnull, ref4 );
executeAction( stringIDToTypeID( "delete" ), desc9, DialogModes.NO );
};
};
// reset;
app.preferences.rulerUnits = originalRulerUnits;
};
////////////////////////////////////
////// collect shape layers //////
function collectShapeLayers () {
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
var theKind = layerDesc.getInteger(stringIDToTypeID('layerKind'));
var hasLayerMask = layerDesc.hasKey(charIDToTypeID("Usrs"));
var hasStroke = layerDesc.hasKey(stringIDToTypeID("AGMStrokeStyleInfo"));
if (hasStroke == true) {hasStroke = layerDesc.getObjectValue(stringIDToTypeID("AGMStrokeStyleInfo")).getBoolean(stringIDToTypeID("strokeEnabled"))};
if (theKind == 4) {
theLayers.push([theName, theID, hasLayerMask, hasStroke])
}
};
}
catch (e) {};
};
return theLayers;
};
////// based on code by mike hale, via paul riggott //////
function selectLayerByID(id,add){ 
add = undefined ? add = false:add 
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), id);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message); 
}
};

 

 

 

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
Participant ,
Apr 06, 2024 Apr 06, 2024

Copy link to clipboard

Copied

Thank you for all this work! This one didn't work for me.

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 ,
Apr 06, 2024 Apr 06, 2024

Copy link to clipboard

Copied

Thank you for the feedback, could you please elaborate how it did not fit your needs, it might help Christof to change/tweak his code.

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
Participant ,
Apr 08, 2024 Apr 08, 2024

Copy link to clipboard

Copied

@PECourtejoie Thank you, yes. Nothing happens when I run it. 

 

ScreenRecording.gif

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 ,
Apr 07, 2024 Apr 07, 2024

Copy link to clipboard

Copied

Could you please provide a file on which the Script failed? 

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
Participant ,
Apr 08, 2024 Apr 08, 2024

Copy link to clipboard

Copied

@c.pfaffenbichler Thank you, certainly. I just made a brand new PSD with three circles.

 

Here's a link, but this is just from my Dropbox so it won't be permanent.

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 ,
Apr 08, 2024 Apr 08, 2024

Copy link to clipboard

Copied

Thanks! 

 

The layers’ stroke settings seem to be different (though there is no stroke) from the test file I had created. 

I amended the code in the old post if you want to try it again. 

 

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
Participant ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

Wow, that's amazing! It did all of the layers at once. What a gift! Thank you for working on this. This will enable me to do more than I could before.

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
Participant ,
Jun 27, 2024 Jun 27, 2024

Copy link to clipboard

Copied

@c.pfaffenbichler I am still using your fantastic script. Something it does not handle at the moment is a compound shape pasted as a layer from Illustrator. Would that be difficult to add?

 

Steps to reproduce, if needed:

1. Make any compound shape in Illustrator

2. Copy

3. In Photoshop, paste

4. Choose to paste as "Layers"

 

Then try to run the script.

 

Thanks a million.

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 ,
Jun 29, 2024 Jun 29, 2024

Copy link to clipboard

Copied

quote

@c.pfaffenbichler I am still using your fantastic script. Something it does not handle at the moment is a compound shape pasted as a layer from Illustrator. Would that be difficult to add?

 

Steps to reproduce, if needed:

1. Make any compound shape in Illustrator

2. Copy

3. In Photoshop, paste

4. Choose to paste as "Layers"

 

Then try to run the script.

 

Thanks a million.


By @Jack Brannen

 

This creates a raster mask for me and the mask is correct and the fill layer can be easily changed. I'm not seeing the issue?

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
Participant ,
Jul 01, 2024 Jul 01, 2024

Copy link to clipboard

Copied

@Stephen_A_Marsh Thanks for checking. Odd, just tested again and it isn't for me. Let's see what @c.pfaffenbichler says about my test files… I can always record a screencast.

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 ,
Jul 01, 2024 Jul 01, 2024

Copy link to clipboard

Copied

quote

@Stephen_A_Marsh Thanks for checking. Odd, just tested again and it isn't for me. Let's see what @c.pfaffenbichler says about my test files… I can always record a screencast.


By @Jack Brannen


It results in a solid fill layer with raster mask for me. I'll also try your test file.

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 ,
Jun 30, 2024 Jun 30, 2024

Copy link to clipboard

Copied

Could you provide the ai and the psd with the pasted content for testing? 

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
Participant ,
Jul 01, 2024 Jul 01, 2024

Copy link to clipboard

Copied

@c.pfaffenbichler Yes, thanks! Attached.

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 ,
Jul 01, 2024 Jul 01, 2024

Copy link to clipboard

Copied

Thank you; Compound Shapes seem to paste as a plain pixel Layer when set to »Layers«, so there is no vector mask. 

 

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
Participant ,
Jul 02, 2024 Jul 02, 2024

Copy link to clipboard

Copied

LATEST

@c.pfaffenbichler @Stephen_A_Marsh So weird that we're all getting different results. I bet there are paste setting involved somewhere.

 

@c.pfaffenbichler I get a shape layer when I paste a compound shape:

JackBrannen_0-1719929946868.jpeg

 

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 ,
Apr 06, 2024 Apr 06, 2024

Copy link to clipboard

Copied

One more thing came to my mind: 

What about Shape Layers with a Stroke? 

edit: updated the code

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