Copy link to clipboard
Copied
Hi, we're using PS CC 2017. Doing lots of images including working paths for retouching purposes we finally want to get rid of those paths if being saved as flat tif. But as far as I know Photoshop only allows to manually select and delete those paths.
Is there any workaround to do that automatically with script or Photoshop action.
many thanks for any advice!
br Christian
It can be done via a Script, but the following would include a selected Shape Layer, so you could either amend the Script or use it after flattening.
// 2017, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
try {activeDocument.pathItems.removeAll()}
catch (e) {}
};
Edit: Also see
and maybe post on the Photoshop Scripting Forum.
Copy link to clipboard
Copied
It can be done via a Script, but the following would include a selected Shape Layer, so you could either amend the Script or use it after flattening.
// 2017, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
try {activeDocument.pathItems.removeAll()}
catch (e) {}
};
Edit: Also see
and maybe post on the Photoshop Scripting Forum.
Copy link to clipboard
Copied
"... but the following would include a selected Shape Layer, so you could either amend the Script ..."
Oh, how I have tried, without success since this topic thread:
Copy link to clipboard
Copied
this deletes paths only no matter how many or what they are named it doesnt touch layers, if thats what you mean
Copy link to clipboard
Copied
Have you actually tried the script with a shape layer in the file?
Copy link to clipboard
Copied
do you want to keep the shape layer and shape layer path and delete all other paths?
I will try to make it do that if that is what your looking for, or do you want to keep the shape layer with no path? not sure how to do that.
Copy link to clipboard
Copied
I just revised this and it keeps all layers including the shape layer and shape layer path but deletes all other paths. I just added a command to turn off all layers in photoshop, run the path deletion part of the script and then turn all layers back on and then save.
on open fileList
tell application "Adobe Photoshop CC 2018"
activate
repeat with thisFile in fileList
open thisFile showing dialogs never
try
set myDoc to current document
end try
tell application "System Events" to tell process "Adobe Photoshop CC 2018"
set frontmost to true
keystroke "a" using {option down, command down}
keystroke "," using {command down}
end tell
tell myDoc
repeat while first path item exists
if first path item exists then
delete first path item
end if
end repeat
tell application "Adobe Photoshop CC 2018"
activate
tell application "System Events" to tell process "Adobe Photoshop CC 2018"
set frontmost to true
keystroke "," using {command down}
end tell
end tell
close saving yes
end tell
end repeat
end tell
end open
Copy link to clipboard
Copied
"I just added a command to turn off all layers in photoshop, run the path deletion part of the script and then turn all layers back on and then save."
Thank you stevef55565652 that is a very clever idea!
Although JS can't send keystrokes, I can emulate these steps using menu calls or script listener code.
Copy link to clipboard
Copied
"do you want to keep the shape layer and shape layer path and delete all other paths?"
Yes, however, I would like the ability to include/exclude different path kinds (clipping, normal, work) while retaining shape layers.
Copy link to clipboard
Copied
Stephen, could you try this:
// 2020, use it at your own risk;
if (app.documents.length > 0) {
////// deselect layers //////
var desc2 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putEnumerated( stringIDToTypeID( "layer" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
desc2.putReference( stringIDToTypeID( "null" ), ref1 );
executeAction( stringIDToTypeID( "selectNoLayers" ), desc2, DialogModes.NO );
////// get paths //////
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var docDesc = executeActionGet(ref);
if (docDesc.hasKey(stringIDToTypeID("numberOfPaths")) == true) {
var theNumber = docDesc.getInteger(stringIDToTypeID("numberOfPaths"));
var theArray = new Array;
////// work through paths //////
for (var m = 0; m < theNumber+1; m++) {
try {
var ref = new ActionReference();
ref.putIndex( stringIDToTypeID( "path" ), m);
var pathDesc = executeActionGet(ref);
var theName = pathDesc.getString(stringIDToTypeID("pathName"));
var theKind = pathDesc.getEnumerationValue(stringIDToTypeID("kind"));
var theIndex = pathDesc.getInteger(stringIDToTypeID("itemIndex"));
theArray.push([theName, theKind, theIndex]);
} catch (e) {}
};
////// delete //////
for (var n = theNumber-1; n >= 0; n--) {
var desc4 = new ActionDescriptor();
var ref2 = new ActionReference();
ref2.putIndex( stringIDToTypeID( "path" ), theArray[n][2] );
desc4.putReference( stringIDToTypeID( "null" ), ref2 );
executeAction( stringIDToTypeID( "delete" ), desc4, DialogModes.NO );
};
};
};
Copy link to clipboard
Copied
thank you c_pfaffenbichler for the code! It does indeed work, however, as I mentioned in the other referenced topic I have been looking for fine control over which path types are removed/retained. This could be for many paths in a single file or perhaps performed on many files in a batch.
The challenge is having the ability to:
i) Include/Exclude a particular PathKind (CLIPPINGPATH or NORMALPATH or WORKPATH)
ii) Not removing shape layers
Perhaps the most common "cleanup" would be to provide a client with a duped final file (layered or flattened) that contained a clipping path – so all saved normal paths and work paths would be removed, while clipping paths and shape layers would be retained.
Copy link to clipboard
Copied
I was being lazy and just had the Script deselect all Layers so that Vector Masks and Shape Layers would simply not be listed among the Paths …
Here is a version that would not delete the Clipping Path, the ID for Work Path is in a comment.
// 2020, use it at your own risk;
if (app.documents.length > 0) {
////// deselect layers //////
var desc2 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putEnumerated( stringIDToTypeID( "layer" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
desc2.putReference( stringIDToTypeID( "null" ), ref1 );
executeAction( stringIDToTypeID( "selectNoLayers" ), desc2, DialogModes.NO );
////// get paths //////
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var docDesc = executeActionGet(ref);
if (docDesc.hasKey(stringIDToTypeID("numberOfPaths")) == true) {
var theNumber = docDesc.getInteger(stringIDToTypeID("numberOfPaths"));
var theArray = new Array;
////// work through paths //////
for (var m = 0; m < theNumber+1; m++) {
try {
var ref = new ActionReference();
ref.putIndex( stringIDToTypeID( "path" ), m);
var pathDesc = executeActionGet(ref);
var theName = pathDesc.getString(stringIDToTypeID("pathName"));
var theKind = pathDesc.getEnumerationValue(stringIDToTypeID("kind"));
var theIndex = pathDesc.getInteger(stringIDToTypeID("itemIndex"));
theArray.push([theName, theKind, theIndex]);
} catch (e) {}
};
alert (theArray.join("\n"));
////// delete //////
for (var n = theNumber-1; n >= 0; n--) {
// work paths 1467116368;
if (theArray[n][1] != 1131180112) {
var desc4 = new ActionDescriptor();
var ref2 = new ActionReference();
ref2.putIndex( stringIDToTypeID( "path" ), theArray[n][2] );
desc4.putReference( stringIDToTypeID( "null" ), ref2 );
executeAction( stringIDToTypeID( "delete" ), desc4, DialogModes.NO );
};
};
};
};
Copy link to clipboard
Copied
Thank you c_pfaffenbichler that was what I have been trying to achieve with standard code!
Copy link to clipboard
Copied
I have had to incorporate an "if/else" routine to check for flattened and layered content in order to run two sets of code – one for a flattened image with paths and another for layered images with paths.
Some things that I have learnt about scripting from this topic thread:
1) Test with a flattened image, as results may differ from a layered image
2) Test with a layered image, as results may differ from a flattened image
3) Test with different layers and layer sets visible as results may vary
4) Test with different layers and layer sets selected as results may vary
5) Test with no layers selected as results may vary
6) c_pfaffenbichler must be like Neo from the Matrix movie series, seeing the world in hidden code! :]
Copy link to clipboard
Copied
Oh, no, I am still very much uncomfortable with AM code.
And what I can achieve with it is owed in large parts to xbytor, Paul Riggott and Michael L Hale (and other regulars at the old Photoshop Scripting Forum) a couple years back.
I am not trying to downplay the efforts and achievements of others by not mentioning them by name, but with those three it happened that they were very active when I started looking into Photoshop Scripting myself.
Their knowledge and their willingness to share it with others were impressive and a great boon to the Forum.
Copy link to clipboard
Copied
Thank you c_pfaffenbichler your code has helped me update a project that has been stalled for a couple of years!
Copy link to clipboard
Copied
This is the first script that I have posted. I have been helped by many other people on this site so I thought I would put this one on.
This is a applescript droplet that deletes all paths and saves the image. Change the tell appplication
"Adobe Photoshop CC 2018" to whatever version of photoshop your using.
This script deletes the first path item while the first path item exists and repeats until there is no first path items.
I had to delete all the paths from the images that I was retouching for work so I made this. It's just pieces of other scripts I found, but seems to work well for me.
Copy the script into Script Editor and export as an application to your desktop and uncheck all 3 options before saving. You can drop your images on it and the paths will be deleted.
on open fileList
tell application "Adobe Photoshop CC 2018"
activate
repeat with thisFile in fileList
open thisFile showing dialogs never
try
set myDoc to current document
end try
tell myDoc
repeat while first path item exists
if first path item exists then
delete first path item
end if
end repeat
close saving yes
end tell
end repeat
end tell
end open
Copy link to clipboard
Copied
Hi stevef55565652 thank you for sharing your code and bumping this topic!
Copy link to clipboard
Copied
Moderator label this thread as 'Actions and scripting'.
Copy link to clipboard
Copied
I stumbled over this old topic and thought that I should update it with the current code that I use.
removeAllClipPaths()
function removeAllClipPaths() {
// Stephen Marsh, 2022
// Hide the active layer to ensure that vector shape paths are not inadvertently removed!
var docPaths = activeDocument.pathItems;
if (app.activeDocument.activeLayer.isBackgroundLayer) {
clipPathRemover();
} else {
if (activeDocument.activeLayer.visible == false) {
clipPathRemover();
} else {
activeDocument.activeLayer.visible = false;
clipPathRemover();
activeDocument.activeLayer.visible = true;
}
}
function clipPathRemover() {
for (i = docPaths.length - 1; i > -1; i--) {
thePaths = docPaths[i];
if (thePaths.kind == "PathKind.CLIPPINGPATH") {
thePaths.remove()
}
}
}
}
removeAllNormalPaths();
function removeAllNormalPaths() {
// Stephen Marsh, 2022
// Hide the active layer to ensure that vector shape paths are not inadvertently removed!
var docPaths = activeDocument.pathItems;
if (app.activeDocument.activeLayer.isBackgroundLayer) {
normalPathRemover();
} else {
if (activeDocument.activeLayer.visible == false) {
normalPathRemover();
} else {
activeDocument.activeLayer.visible = false;
normalPathRemover();
activeDocument.activeLayer.visible = true;
}
}
function normalPathRemover() {
for (i = docPaths.length - 1; i > -1; i--) {
thePaths = docPaths[i];
if (thePaths.kind == "PathKind.NORMALPATH") {
thePaths.remove()
}
}
}
}
removeAllWorkPaths();
function removeAllWorkPaths() {
// Stephen Marsh, 2022
// Hide the active layer to ensure that vector shape paths are not inadvertently removed!
var docPaths = activeDocument.pathItems;
if (app.activeDocument.activeLayer.isBackgroundLayer) {
workPathRemover();
} else {
if (activeDocument.activeLayer.visible == false) {
workPathRemover();
} else {
activeDocument.activeLayer.visible = false;
workPathRemover();
activeDocument.activeLayer.visible = true;
}
}
function workPathRemover() {
for (i = docPaths.length - 1; i > -1; i--) {
thePaths = docPaths[i];
if (thePaths.kind == "PathKind.WORKPATH") {
thePaths.remove()
}
}
}
}