Skip to main content
Participant
February 25, 2019
Answered

Vector rectangle shape made with ExtendScript?

  • February 25, 2019
  • 3 replies
  • 2818 views

Hello,

Is it possible to create a vector rectangle shape (rectangle tool) with ExtendScript?

I just want to create a 1px border around my PSD file and keep it vector in order to change the width later (to 2px for example).

Thanks for your help,

fred

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

Maybe this is what you need.

var w = 1; // px

var tmp = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS;

var x = activeDocument.width.value;

var y = activeDocument.height.value;

app.preferences.rulerUnits = tmp;

var d = new ActionDescriptor();

var r = new ActionReference();

r.putClass(stringIDToTypeID("contentLayer"));

d.putReference(stringIDToTypeID("null"), r);

var d1 = new ActionDescriptor();

d1.putObject(stringIDToTypeID("type"), stringIDToTypeID("solidColorLayer"), new ActionDescriptor());

var d2 = new ActionDescriptor();

d2.putUnitDouble(stringIDToTypeID("top"),    stringIDToTypeID("pixelsUnit"), 0);

d2.putUnitDouble(stringIDToTypeID("left"),   stringIDToTypeID("pixelsUnit"), 0);

d2.putUnitDouble(stringIDToTypeID("bottom"), stringIDToTypeID("pixelsUnit"), y);

d2.putUnitDouble(stringIDToTypeID("right"),  stringIDToTypeID("pixelsUnit"), x);

d1.putObject(stringIDToTypeID("shape"), stringIDToTypeID("rectangle"), d2);

var d2 = new ActionDescriptor();

d2.putBoolean(stringIDToTypeID("strokeEnabled"), true);

d2.putBoolean(stringIDToTypeID("fillEnabled"), false);

d2.putUnitDouble(stringIDToTypeID("strokeStyleLineWidth"), stringIDToTypeID("pixelsUnit"), w);

var d3 = new ActionDescriptor();

d3.putDouble(stringIDToTypeID("red"),   0);

d3.putDouble(stringIDToTypeID("green"), 0);

d3.putDouble(stringIDToTypeID("blue"),  0);

var d4 = new ActionDescriptor();

d4.putObject(stringIDToTypeID("color"), stringIDToTypeID("RGBColor"), d3);

d2.putObject(stringIDToTypeID("strokeStyleContent"), stringIDToTypeID("solidColorLayer"), d4);

d1.putObject(stringIDToTypeID("strokeStyle"), stringIDToTypeID("strokeStyle"), d2);

d.putObject(stringIDToTypeID("using"), stringIDToTypeID("contentLayer"), d1);

executeAction(stringIDToTypeID("make"), d, DialogModes.NO);

3 replies

Participant
September 19, 2022

For anyone looking at the code in this discussion thinking that it looks like magic... Well, I was with you there.

I HIGHLY suggest installing the ScriptListener plugin:
https://helpx.adobe.com/photoshop/kb/downloadable-plugins-and-content.html

IF you are on an M1 mac (like I am), run Photoshop using Rosetta (the plugin does not run natively on m1 chips yet).

You might also need to notarize the plugin. After putting the plugin in the Plugins folder, open terminal and run below:

sudo xattr -dr com.apple.quarantine /Applications/Adobe\ Photoshop\ 2022/Plug-ins/ScriptingListener.plugin

 

Once you have this plugin working... Trust me, you will be glad you did this. It will accelerate the development of ExtendScript's by orders of magnitude. Look at the desktop and it will show you the actions Photoshop executed and you can port this over into your jsx.

fr3dAuthor
Participant
March 28, 2019

Hello again...

I would like to have a background color within this script... how can I do that?

I tried to set the following to true, it works but I have a default white bgd and I want to change the color.

d2.putBoolean(stringIDToTypeID("fillEnabled"), true);

Thank you,

fred

  • var w = 1; // px 
  •  
  • var tmp = app.preferences.rulerUnits; 
  •  
  • app.preferences.rulerUnits = Units.PIXELS; 
  •  
  • var x = activeDocument.width.value; 
  • var y = activeDocument.height.value; 
  •  
  • app.preferences.rulerUnits = tmp; 
  •  
  • var d = new ActionDescriptor(); 
  • var r = new ActionReference(); 
  • r.putClass(stringIDToTypeID("contentLayer")); 
  • d.putReference(stringIDToTypeID("null"), r); 
  • var d1 = new ActionDescriptor(); 
  • d1.putObject(stringIDToTypeID("type"), stringIDToTypeID("solidColorLayer"), new ActionDescriptor()); 
  • var d2 = new ActionDescriptor(); 
  • d2.putUnitDouble(stringIDToTypeID("top"),    stringIDToTypeID("pixelsUnit"), 0); 
  • d2.putUnitDouble(stringIDToTypeID("left"),   stringIDToTypeID("pixelsUnit"), 0); 
  • d2.putUnitDouble(stringIDToTypeID("bottom"), stringIDToTypeID("pixelsUnit"), y); 
  • d2.putUnitDouble(stringIDToTypeID("right"),  stringIDToTypeID("pixelsUnit"), x); 
  • d1.putObject(stringIDToTypeID("shape"), stringIDToTypeID("rectangle"), d2); 
  • var d2 = new ActionDescriptor(); 
  • d2.putBoolean(stringIDToTypeID("strokeEnabled"), true); 
  • d2.putBoolean(stringIDToTypeID("fillEnabled"), false); 
  • d2.putUnitDouble(stringIDToTypeID("strokeStyleLineWidth"), stringIDToTypeID("pixelsUnit"), w); 
  • var d3 = new ActionDescriptor(); 
  • d3.putDouble(stringIDToTypeID("red"),   0); 
  • d3.putDouble(stringIDToTypeID("green"), 0); 
  • d3.putDouble(stringIDToTypeID("blue"),  0); 
  • var d4 = new ActionDescriptor(); 
  • d4.putObject(stringIDToTypeID("color"), stringIDToTypeID("RGBColor"), d3); 
  • d2.putObject(stringIDToTypeID("strokeStyleContent"), stringIDToTypeID("solidColorLayer"), d4); 
  • d1.putObject(stringIDToTypeID("strokeStyle"), stringIDToTypeID("strokeStyle"), d2); 
  • d.putObject(stringIDToTypeID("using"), stringIDToTypeID("contentLayer"), d1); 
  • executeAction(stringIDToTypeID("make"), d, DialogModes.NO);
JJMack
Community Expert
Community Expert
March 28, 2019

You would been to add a layer below the Shape layer and fill the layer with the color you want.

JJMack
fr3dAuthor
Participant
March 28, 2019

Thanks for your answer, but I would prefer to keep the Live Shape Properties of the Rectangle Tool... and use the Fill Color like it is already with the stroke color...

r-binCorrect answer
Legend
February 26, 2019

Maybe this is what you need.

var w = 1; // px

var tmp = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS;

var x = activeDocument.width.value;

var y = activeDocument.height.value;

app.preferences.rulerUnits = tmp;

var d = new ActionDescriptor();

var r = new ActionReference();

r.putClass(stringIDToTypeID("contentLayer"));

d.putReference(stringIDToTypeID("null"), r);

var d1 = new ActionDescriptor();

d1.putObject(stringIDToTypeID("type"), stringIDToTypeID("solidColorLayer"), new ActionDescriptor());

var d2 = new ActionDescriptor();

d2.putUnitDouble(stringIDToTypeID("top"),    stringIDToTypeID("pixelsUnit"), 0);

d2.putUnitDouble(stringIDToTypeID("left"),   stringIDToTypeID("pixelsUnit"), 0);

d2.putUnitDouble(stringIDToTypeID("bottom"), stringIDToTypeID("pixelsUnit"), y);

d2.putUnitDouble(stringIDToTypeID("right"),  stringIDToTypeID("pixelsUnit"), x);

d1.putObject(stringIDToTypeID("shape"), stringIDToTypeID("rectangle"), d2);

var d2 = new ActionDescriptor();

d2.putBoolean(stringIDToTypeID("strokeEnabled"), true);

d2.putBoolean(stringIDToTypeID("fillEnabled"), false);

d2.putUnitDouble(stringIDToTypeID("strokeStyleLineWidth"), stringIDToTypeID("pixelsUnit"), w);

var d3 = new ActionDescriptor();

d3.putDouble(stringIDToTypeID("red"),   0);

d3.putDouble(stringIDToTypeID("green"), 0);

d3.putDouble(stringIDToTypeID("blue"),  0);

var d4 = new ActionDescriptor();

d4.putObject(stringIDToTypeID("color"), stringIDToTypeID("RGBColor"), d3);

d2.putObject(stringIDToTypeID("strokeStyleContent"), stringIDToTypeID("solidColorLayer"), d4);

d1.putObject(stringIDToTypeID("strokeStyle"), stringIDToTypeID("strokeStyle"), d2);

d.putObject(stringIDToTypeID("using"), stringIDToTypeID("contentLayer"), d1);

executeAction(stringIDToTypeID("make"), d, DialogModes.NO);

fr3dAuthor
Participant
March 5, 2019

Hi r-bin,

Thank you so much for your code, this is perfect

fred