Copy link to clipboard
Copied
Hello!
I'm trying to write a photoshop script that can change the size of strokes on all shape layers.
When we increase the image size, none of the stroke widths scale with that change. This is what we are trying to fix. Is there a way to increase image size and have stroke width also scale?
It seems super simple and I can do it in Adobe Animate really easily, but not photoshop.
So far I can get the stroke size of an active layer but not change it... (thanks to another great post)...
Please help!! 😮
var activeDoc = app.activeDocument;
var layers = activeDoc.layers;
var layerLength = layers.length;
//alert(layers.length);
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("AGMStrokeStyleInfo"));
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
//alert(executeActionGet(r).getObjectValue(stringIDToTypeID("AGMStrokeStyleInfo")).getUnitDoubleValue(stringIDToTypeID("strokeStyleLineWidth")));
var strokeSize = (executeActionGet(r).getObjectValue(stringIDToTypeID("AGMStrokeStyleInfo")).getUnitDoubleValue(stringIDToTypeID("strokeStyleLineWidth")));
alert(strokeSize);
strokeSize += 10;
#target photoshop
var s2t = stringIDToTypeID,
delta = 10;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var len = executeActionGet(r).getInteger(p),
lrs = [];
for (var i = 1; i <= len; i++) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerKind'));
r.putIndex(s2t('layer'), i);
if (executeActionGet(r).getInteger(p) == 4) {
(r = new Ac
...
Copy link to clipboard
Copied
I would use scriptListener and record changing the stroke size, then make a function out of that code and replace the amount you changed the stroke size with a variable.
Copy link to clipboard
Copied
Oooh thankyou Chuck!
Why have i not heard of this before!
I'll try it out!! 😁
Copy link to clipboard
Copied
Hmmm It seems to be what I want.... but I can't wrap my head around why it's not working....
If i paste the code I got from the listener and run it... I just get the error:
"stringIDToTypeID is not a function"
If I then make it a function.. The script runs... but nothing happens.
I think I must be missing something?
// =======================================================
var idhistoryStateChanged = stringIDToTypeID( "historyStateChanged" );
var desc298 = new ActionDescriptor();
var idDocI = charIDToTypeID( "DocI" );
desc298.putInteger( idDocI, 251 );
var idIdnt = charIDToTypeID( "Idnt" );
desc298.putInteger( idIdnt, 278 );
var idNm = charIDToTypeID( "Nm " );
desc298.putString( idNm, """Set Shape Layer Stroke""" );
var idhasEnglish = stringIDToTypeID( "hasEnglish" );
desc298.putBoolean( idhasEnglish, true );
var idItmI = charIDToTypeID( "ItmI" );
desc298.putInteger( idItmI, 11 );
executeAction( idhistoryStateChanged, desc298, DialogModes.NO );
// =======================================================
var idsetd = charIDToTypeID( "setd" );
var desc299 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref16 = new ActionReference();
var idcontentLayer = stringIDToTypeID( "contentLayer" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref16.putEnumerated( idcontentLayer, idOrdn, idTrgt );
desc299.putReference( idnull, ref16 );
var idT = charIDToTypeID( "T " );
var desc300 = new ActionDescriptor();
var idstrokeStyle = stringIDToTypeID( "strokeStyle" );
var desc301 = new ActionDescriptor();
var idstrokeStyleLineWidth = stringIDToTypeID( "strokeStyleLineWidth" );
var idPxl = charIDToTypeID( "#Pxl" );
desc301.putUnitDouble( idstrokeStyleLineWidth, idPxl, 5.200000 );
var idstrokeStyleVersion = stringIDToTypeID( "strokeStyleVersion" );
desc301.putInteger( idstrokeStyleVersion, 2 );
var idstrokeEnabled = stringIDToTypeID( "strokeEnabled" );
desc301.putBoolean( idstrokeEnabled, true );
var idstrokeStyle = stringIDToTypeID( "strokeStyle" );
desc300.putObject( idstrokeStyle, idstrokeStyle, desc301 );
var idshapeStyle = stringIDToTypeID( "shapeStyle" );
desc299.putObject( idT, idshapeStyle, desc300 );
executeAction( idsetd, desc299, DialogModes.NO );
Copy link to clipboard
Copied
WAIT! I worked it out..... I'm an idiot..
I just wasn't pointing to photoshop.......
I can successfully change the width of the selected layer.
But I can't find an easy solution to cycle through ALL the layers ... (even the nested ones)
Please help! 🥰
Copy link to clipboard
Copied
There is a fast way to do this with AM code, which I'm not that good with. Others who help on this site might offer better suggestions. The slow way is a recursive function where you put in document into the function, and it searches all its children (layers) for stroked layers. If it comes across a layer set, it recalls the function with the layer set and searches all its children.
Copy link to clipboard
Copied
Yes I would have definitely done it the slow way! hahahah
Is there any good places to learn about this AM code?
It seems to be sooo much different to normal javascript.
I'm used to working with JSFL in Adobe Animate!
Thanks for your help Chuck!
Copy link to clipboard
Copied
There is a great topic thread on the forum, however this is the only in depth material that I know of:
https://www.ps-scripting.com/ps-scripting.html
Copy link to clipboard
Copied
Davide Barranca's book on scripting is a great way to learn scripting.
https://www.davidebarranca.com/2019/02/professional-photoshop-scripting-v1/
Copy link to clipboard
Copied
#target photoshop
var s2t = stringIDToTypeID,
delta = 10;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var len = executeActionGet(r).getInteger(p),
lrs = [];
for (var i = 1; i <= len; i++) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerKind'));
r.putIndex(s2t('layer'), i);
if (executeActionGet(r).getInteger(p) == 4) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerID'));
r.putIndex(s2t('layer'), i);
lrs.push(executeActionGet(r).getInteger(p));
}
}
if (lrs.length) {
for (var i = 0; i < lrs.length; i++) {
(r = new ActionReference()).putIdentifier(s2t('layer'), lrs[i]);
(d = new ActionDescriptor()).putReference(s2t('null'), r);
executeAction(s2t('select'), d, DialogModes.NO);
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('AGMStrokeStyleInfo'));
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
var strokeSize = executeActionGet(r).getObjectValue(p).getUnitDoubleValue(s2t('strokeStyleLineWidth'));
(r = new ActionReference()).putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putReference(s2t("null"), r);
(d1 = new ActionDescriptor()).putUnitDouble(s2t("strokeStyleLineWidth"), s2t("pixelsUnit"), strokeSize + delta);
(d2 = new ActionDescriptor()).putObject(s2t("strokeStyle"), s2t("strokeStyle"), d1);
d.putObject(s2t("to"), s2t("shapeStyle"), d2);
executeAction(s2t("set"), d, DialogModes.NO);
}
}
Copy link to clipboard
Copied
WOO!
HIGH FIVE!
Thankyou so much for this.
I ... am not familiar at all with this scripting style. AM code.
I shall have to look further into it.
But thankyou thankyou thankyou! 🤩
Copy link to clipboard
Copied
HI Jazz-y!
I know you're probably super busy, but I seem to have run into a problem and there doesn't seem to be a place to find help.
This is my script as I have it so far.
I just want to increase or decrease the line width on all layers (if they have it)
But it gets stuck on these specific layers which don't SEEM to have any "strokeStyleLineWidth"
line 39 >>
var strokeSize = executeActionGet(r).getObjectValue(p).getUnitDoubleValue(s2t('strokeStyleLineWidth'));
it just gives me the error message.
"general photoshop error occurred. this functionality may not be available in this version of photoshop"
But if I give the layer a colour and then make it transparent again.... it works??
Is there a way to skip a layer if it's line colour is set to nothing?
e.g.
If(linewdith colour == null ){move on}
?
Please help you are a hero on these forums!
#target photoshop
var s2t = stringIDToTypeID,
//var newStrokeSize = 10;
newStrokeSize = prompt("Enter the % increase for linewidth","","input value here");
newStrokeSize = newStrokeSize /100;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var len = executeActionGet(r).getInteger(p),
lrs = [];
for (var i = 1; i <= len; i++) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerKind'));
r.putIndex(s2t('layer'), i);
if (executeActionGet(r).getInteger(p) == 4) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerID'));
r.putIndex(s2t('layer'), i);
lrs.push(executeActionGet(r).getInteger(p));
}
}
if (lrs.length) {
for (var i = 0; i < lrs.length; i++) {
(r = new ActionReference()).putIdentifier(s2t('layer'), lrs[i]);
(d = new ActionDescriptor()).putReference(s2t('null'), r);
executeAction(s2t('select'), d, DialogModes.NO);
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('AGMStrokeStyleInfo'));
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
var strokeSize = executeActionGet(r).getObjectValue(p).getUnitDoubleValue(s2t('strokeStyleLineWidth'));
(r = new ActionReference()).putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putReference(s2t("null"), r);
//(d1 = new ActionDescriptor()).putUnitDouble(s2t("strokeStyleLineWidth"), s2t("pixelsUnit"), strokeSize + (strokeSize*newStrokeSize));
(d1 = new ActionDescriptor()).putUnitDouble(s2t("strokeStyleLineWidth"), s2t("pixelsUnit"), strokeSize = newStrokeSize);
(d2 = new ActionDescriptor()).putObject(s2t("strokeStyle"), s2t("strokeStyle"), d1);
d.putObject(s2t("to"), s2t("shapeStyle"), d2);
executeAction(s2t("set"), d, DialogModes.NO);
}
}
Copy link to clipboard
Copied
I can't reproduce the error on the latest photoshop. Try this variant: I added a check if the stroke is enabled and additionally check if there is a key with its width.
/**Photoshop script to iterate through all layers and change shape stroke size!??!
* https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-script-to-iterate-through-all-layers-and-change-shape-stroke-size/td-p/12689665
*/
#target photoshop
var s2t = stringIDToTypeID,
delta = 10;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var len = executeActionGet(r).getInteger(p),
lrs = [];
for (var i = 1; i <= len; i++) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerKind'));
r.putIndex(s2t('layer'), i);
if (executeActionGet(r).getInteger(p) == 4) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerID'));
r.putIndex(s2t('layer'), i);
lrs.push(executeActionGet(r).getInteger(p));
}
}
if (lrs.length) {
for (var i = 0; i < lrs.length; i++) {
(r = new ActionReference()).putIdentifier(s2t('layer'), lrs[i]);
(d = new ActionDescriptor()).putReference(s2t('null'), r);
executeAction(s2t('select'), d, DialogModes.NO);
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('AGMStrokeStyleInfo'));
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
var stroke = executeActionGet(r).getObjectValue(p);
if (stroke.getBoolean(s2t('strokeEnabled'))) {
var strokeSize = stroke.hasKey(p = s2t('strokeStyleLineWidth')) ? stroke.getUnitDoubleValue(p) : 0;
(r = new ActionReference()).putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putReference(s2t("null"), r);
(d1 = new ActionDescriptor()).putUnitDouble(s2t("strokeStyleLineWidth"), s2t("pixelsUnit"), strokeSize + delta);
(d2 = new ActionDescriptor()).putObject(s2t("strokeStyle"), s2t("strokeStyle"), d1);
d.putObject(s2t("to"), s2t("shapeStyle"), d2);
executeAction(s2t("set"), d, DialogModes.NO);
}
}
}
Copy link to clipboard
Copied
jazz-y 😁
Thankyou so much!
I also updated Photoshop and it still doesn't work! 😢
Unforuntately it must be something to do with the specific PSD files I'm working with 🤔😕
The layer "c3 drop copy" is the problematic one.
It gets stuck on line 32
var stroke = executeActionGet(r).getObjectValue(p);
It's like it can't find any value for the TypeID
p = s2t('AGMStrokeStyleInfo')
In the layer "c3 drop copy"
As soon as you change the value of the stroke it works...
but we have thousands of layers in our PSDs... so that's not feasible.
I tried declaring the var stroke = 10;
...to make sure it had a value... but no success. 😢
I added in a scriptlistener CHUNK (below)
and..... that seemed to over ride the error....
but changes ALL the layers.
This seems overly complicated for something so simple...
Is there another way to access these functions through PS Javascript ?
Any genius insights you have would be most appreciated!
/**Photoshop script to iterate through all layers and change shape stroke size!??!
* https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-script-to-iterate-through-all-layers-and-change-shape-stroke-size/td-p/12689665
*/
#target photoshop
var s2t = stringIDToTypeID,
delta = 10;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var len = executeActionGet(r).getInteger(p),
lrs = [];
for (var i = 1; i <= len; i++) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerKind'));
r.putIndex(s2t('layer'), i);
if (executeActionGet(r).getInteger(p) == 4) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerID'));
r.putIndex(s2t('layer'), i);
lrs.push(executeActionGet(r).getInteger(p));
}
}
if (lrs.length) {
for (var i = 0; i < lrs.length; i++) {
(r = new ActionReference()).putIdentifier(s2t('layer'), lrs[i]);
(d = new ActionDescriptor()).putReference(s2t('null'), r);
executeAction(s2t('select'), d, DialogModes.NO);
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('AGMStrokeStyleInfo'));
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
// =======================================================
var idsetd = charIDToTypeID( "setd" );
var desc398 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref18 = new ActionReference();
var idcontentLayer = stringIDToTypeID( "contentLayer" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref18.putEnumerated( idcontentLayer, idOrdn, idTrgt );
desc398.putReference( idnull, ref18 );
var idT = charIDToTypeID( "T " );
var desc399 = new ActionDescriptor();
var idstrokeStyle = stringIDToTypeID( "strokeStyle" );
var desc400 = new ActionDescriptor();
var idstrokeStyleContent = stringIDToTypeID( "strokeStyleContent" );
var desc401 = new ActionDescriptor();
var idClr = charIDToTypeID( "Clr " );
var desc402 = new ActionDescriptor();
var idRd = charIDToTypeID( "Rd " );
desc402.putDouble( idRd, 158.011679 );
var idGrn = charIDToTypeID( "Grn " );
desc402.putDouble( idGrn, 255.000000 );
var idBl = charIDToTypeID( "Bl " );
desc402.putDouble( idBl, 0.003891 );
var idRGBC = charIDToTypeID( "RGBC" );
desc401.putObject( idClr, idRGBC, desc402 );
var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );
desc400.putObject( idstrokeStyleContent, idsolidColorLayer, desc401 );
var idstrokeStyleVersion = stringIDToTypeID( "strokeStyleVersion" );
desc400.putInteger( idstrokeStyleVersion, 2 );
var idstrokeEnabled = stringIDToTypeID( "strokeEnabled" );
desc400.putBoolean( idstrokeEnabled, true );
var idstrokeStyle = stringIDToTypeID( "strokeStyle" );
desc399.putObject( idstrokeStyle, idstrokeStyle, desc400 );
var idshapeStyle = stringIDToTypeID( "shapeStyle" );
desc398.putObject( idT, idshapeStyle, desc399 );
executeAction( idsetd, desc398, DialogModes.NO );
var stroke = executeActionGet(r).getObjectValue(p);
if (stroke.getBoolean(s2t('strokeEnabled'))) {
var strokeSize = stroke.hasKey(p = s2t('strokeStyleLineWidth')) ? stroke.getUnitDoubleValue(p) : 0;
(r = new ActionReference()).putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putReference(s2t("null"), r);
(d1 = new ActionDescriptor()).putUnitDouble(s2t("strokeStyleLineWidth"), s2t("pixelsUnit"), strokeSize + delta);
(d2 = new ActionDescriptor()).putObject(s2t("strokeStyle"), s2t("strokeStyle"), d1);
d.putObject(s2t("to"), s2t("shapeStyle"), d2);
executeAction(s2t("set"), d, DialogModes.NO);
}
}
}
Copy link to clipboard
Copied
I tried your file on Windows and OSX and still can't get the error 🙂
Let's try to wrap getting parameters in a try... catch (that is, the script will ignore such layers, but will try to get information about them (if everything is successful, it will write the data to layersLog.txt on the desktop)).
#target photoshop
var s2t = stringIDToTypeID,
delta = 10;
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('numberOfLayers'));
r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
var len = executeActionGet(r).getInteger(p),
lrs = [];
for (var i = 1; i <= len; i++) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerKind'));
r.putIndex(s2t('layer'), i);
if (executeActionGet(r).getInteger(p) == 4) {
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('layerID'));
r.putIndex(s2t('layer'), i);
lrs.push(executeActionGet(r).getInteger(p));
}
}
if (lrs.length) {
var log = [];
for (var i = 0; i < lrs.length; i++) {
(r = new ActionReference()).putIdentifier(s2t('layer'), lrs[i]);
(d = new ActionDescriptor()).putReference(s2t('null'), r);
executeAction(s2t('select'), d, DialogModes.NO);
(r = new ActionReference()).putProperty(s2t('property'), p = s2t('AGMStrokeStyleInfo'));
r.putEnumerated(s2t('contentLayer'), s2t('ordinal'), s2t('targetEnum'));
try {
var stroke = executeActionGet(r).getObjectValue(p);
if (stroke.getBoolean(s2t('strokeEnabled'))) {
var strokeSize = stroke.hasKey(p = s2t('strokeStyleLineWidth')) ? stroke.getUnitDoubleValue(p) : 0;
(r = new ActionReference()).putEnumerated(s2t("contentLayer"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putReference(s2t("null"), r);
(d1 = new ActionDescriptor()).putUnitDouble(s2t("strokeStyleLineWidth"), s2t("pixelsUnit"), strokeSize + delta);
(d2 = new ActionDescriptor()).putObject(s2t("strokeStyle"), s2t("strokeStyle"), d1);
d.putObject(s2t("to"), s2t("shapeStyle"), d2);
executeAction(s2t("set"), d, DialogModes.NO);
}
} catch (e) {
// try to get layer info. remove this if not needed
//==================================================
(r = new ActionReference());
r.putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
(d = new ActionDescriptor()).putObject(s2t('object'), s2t('object'), executeActionGet(r));
log.push(executeAction(s2t('convertJSONdescriptor'), d).getString(s2t('json')))
//==================================================
}
} if (log.length) {
logFile = File(Folder.desktop.fsName + '/' + 'layersLog.txt');
logFile.open('a');
logFile.writeln(log.join('\n'))
logFile.close();
}
}