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

Free script: Remove Selected

Contributor ,
Oct 12, 2018 Oct 12, 2018

Copy link to clipboard

Copied

Hi all,

I wanted to share a super simple script that creates a checkbox for removing Channels, Paths, Colour Pickers and/or LayerComps allowing a simple interface in case you don't always wish to remove all.

Can someone test on Windows for me

#target photoshop  

//Created by Dale R, for public and commercial use

//global variables

var w = new Window('dialog', 'Batch Remove');

w.preferredSize = [50,100];

w.alignChildren = "left"; // align checkboxes to left

// creating buttons and checkboxes

var ck1 = w.add("CheckBox { text: 'Paths', value: false}");

var ck2 = w.add("CheckBox { text: 'Channels', value: false}");

var ck3 = w.add("CheckBox { text: 'Layer Comps', value: false}");

var ck4 = w.add("CheckBox { text: 'Colour Samplers', value: false}");

var p = w.add ('panel', undefined)

p.alignment = "center";

var btn = p.add('button', undefined, 'Run')

p.add ("button", undefined, "Cancel")

btn.onClick =  function () {

    w.close();

    if (ck1.value == true) {

    app.activeDocument.pathItems.removeAll();   

        }

    if (ck2.value == true) {

        app.activeDocument.channels.removeAll();

        }

    if (ck3.value == true) {

        app.activeDocument.layerComps.removeAll();

        }

    if (ck4.value == true) {

        app.activeDocument.colorSamplers.removeAll();

        }

}

w.center();

w.show();

TOPICS
Actions and scripting

Views

12.9K

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
Explorer ,
Oct 12, 2018 Oct 12, 2018

Copy link to clipboard

Copied

What is Colour Samplers?

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
Contributor ,
Oct 12, 2018 Oct 12, 2018

Copy link to clipboard

Copied

When you use the eyedropper tool to see the colour information of the sampled area.

Screen Shot 2018-10-12 at 13.36.25.png

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 ,
Oct 12, 2018 Oct 12, 2018

Copy link to clipboard

Copied

I tried to draw a few color blocks, sucked black and then selected it, but did not remove the black color block.

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 ,
Oct 12, 2018 Oct 12, 2018

Copy link to clipboard

Copied

Why would someone want to delete things they work hard to create. The color sampler tool has a clear all button in its interface why do you need an additional way to do that.

JJMack

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 ,
Oct 12, 2018 Oct 12, 2018

Copy link to clipboard

Copied

Thank you for sharing varDale=undefined

JJ it is a common enough task for some workflows to supply final flattened files to a client without wishing to include all of the “workings” included… However in such a situation I personally would prefer a “silent” approach without an interface as I would be wishing to batch remove the same things every time. As varDale=undefined states the intent is to facilitate clearing various elements with the flexibility to change which elements are cleared each time.

I think that it would be good to have an option to remove all paths and all clipping paths… One may wish to keep the clipping paths, but nothing else.

Another candidate for removal could be the note tool.

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 ,
Oct 12, 2018 Oct 12, 2018

Copy link to clipboard

Copied

A saved jpeg file from a layer document does not have any of your work layers is a flat single layer file that does not support transparency or 16bit color. There is nothing for remove from the jpeg file. And in you work document you would want to selective remove thins like alpha channels  not  remove all channels or all all layer comps etc.  You added then for a reason gloabl remove them is not something most would want to do IMO.

JJMack

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
Contributor ,
Oct 13, 2018 Oct 13, 2018

Copy link to clipboard

Copied

JJ, a jpeg can still hold paths and it may hold channels (can't remember fully).

I've worked for many companies that upload the final TIFF file to their DAM software and if it has alpha channels it can make the preview look wrong, it can mess with colour and make it look like parts are cut out.

I know that not everyone needs to have everything or some items removed, but for those that do, I wanted to share this for them. For me, it is something I use often, so I figured someone else will benefit from it.

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 ,
Oct 13, 2018 Oct 13, 2018

Copy link to clipboard

Copied

Dale, as a newb to scripting, I do appreciate your post and I will use it for my personal learning and sharing in the same spirit.

The syntax is killing me, I am trying to find how to find and remove a particular PathItem PathKind, such as WORKPATH or CLIPPINGPATH or NORMALPATH.

Another thing to remove is guides, I figured that one out easy enough!

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
Contributor ,
Oct 13, 2018 Oct 13, 2018

Copy link to clipboard

Copied

You mean to remove a particular path?

I think you can use:

app.activeDocument.pathItems.getByName("pathname").remove();

However, I am on my phone so cannot test to confirm, but I know that works with layers.

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 ,
Oct 13, 2018 Oct 13, 2018

Copy link to clipboard

Copied

No, not by explicit name (it would work for Work Path, but not for Normal Paths or Clipping Paths which could have any name)… I meant by general PathKind, i.e. is the path a CLIPPINGPATH or WORKPATH or NORMALPATH etc.

 

Similar to here, however I think that the syntax would be different:

 

Need a script for paths and clipping paths

 

I’m sure that there must be a cleaner/better/easier/less verbose way than:

 

var myPath = activeDocument.pathItems;
for(n = myPath.length-1; n>-1; n--) {
	aP = myPath[n];  
	if (aP.kind == "PathKind.WORKPATH") {aP.remove()}
}

 

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 ,
Oct 13, 2018 Oct 13, 2018

Copy link to clipboard

Copied

I hacked the script to include the following options:

 

  • Remove Guides
  • Remove all non-clipping paths

 

hacked.png

 

//https://forums.adobe.com/thread/2546383
//https://forums.adobe.com/message/10675883#10675883

//Added options to remove all paths except clipping paths and to remove all guides

#target photoshop    

//Created by Dale R, for public and commercial use 
//global variables 
var w = new Window('dialog', 'Batch Remove'); 
w.preferredSize = [50,100]; 
w.alignChildren = "left"; // align checkboxes to left 

// creating buttons and checkboxes 
var ck1 = w.add("CheckBox { text: 'Non-Clipping Paths', value: false}"); 
var ck2 = w.add("CheckBox { text: 'Channels', value: false}"); 
var ck3 = w.add("CheckBox { text: 'Layer Comps', value: false}"); 
var ck4 = w.add("CheckBox { text: 'Colour Samplers', value: false}");
var ck5 = w.add("CheckBox { text: 'Guides', value: false}"); 

var p = w.add ('panel', undefined) 
p.alignment = "center"; 
var btn = p.add('button', undefined, 'Run') 
p.add ("button", undefined, "Cancel") 

btn.onClick =  function () { 
    w.close(); 

    if (ck1.value == true) { 
    //https://www.hilfdirselbst.ch/foren/Script_um_Pfade_zu_l%F6schen_P372902.html
    var myPath = activeDocument.pathItems;
    for (n = myPath.length-1; n>-1; n--)
    { aP = myPath[n];
    if(aP.kind != "PathKind.CLIPPINGPATH" ) { aP.remove() }
}
        } 
    if (ck2.value == true) { 
        app.activeDocument.channels.removeAll(); 
        } 
    if (ck3.value == true) { 
        app.activeDocument.layerComps.removeAll(); 
        } 
    if (ck4.value == true) { 
        app.activeDocument.colorSamplers.removeAll(); 
        }
        if (ck5.value == true) { 
        app.activeDocument.guides.removeAll(); 
        } 
} 
w.center(); 
w.show();

However to provide more flexibility, I would prefer to have options for removing specific PathKinds:

 

  • CLIPPINGPATH
  • NORMALPATH
  • WORKPATH

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 ,
Oct 13, 2018 Oct 13, 2018

Copy link to clipboard

Copied

Deleting text sometimes needs

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
Contributor ,
Oct 15, 2018 Oct 15, 2018

Copy link to clipboard

Copied

Very good mate.

The only way I can think of to remove all the non-clipping paths would be to put it in a for loop argument, but that would take some playing around to get it right.

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 ,
Oct 15, 2018 Oct 15, 2018

Copy link to clipboard

Copied

I think that is beyond my rudimentary skills at the moment!

I just thought that a separate checkbox for Clipping Paths, Saved/Normal Paths and Work Paths would be more flexible than a single checkbox.

I have looked around for days and there does not appear to be a “single line” of script code that can both identify and remove a particular path kind… and when I have tried to add more complex code to handle each type of path kind, the final script does not run.

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 ,
Oct 15, 2018 Oct 15, 2018

Copy link to clipboard

Copied

if (ck1.value == true) {   
	//https://www.hilfdirselbst.ch/foren/Script_um_Pfade_zu_l%F6schen_P372902.html 
	var myPath = activeDocument.pathItems;  
	for (n = myPath.length-1; n>-1; n--) {
		aP = myPath[n];  
		if(aP.kind != "PathKind.CLIPPINGPATH" ) { aP.remove() }  
	}
} 

Hi

be careful. You forget the important warning comment from my old posting in the german speaking forum www.hilfdirselbst.ch:

// Achtung --> alle Pfade ausser Beschneidungspfad werden ohne Nachfrage entfernt

// Achtung --> Das betriftt !!!AUCH alle Formebenen!!!

 

that means: all paths, if not a clipping path, will be removed - also from shape layers! - if a shape layer is the active layer

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 ,
Oct 15, 2018 Oct 15, 2018

Copy link to clipboard

Copied

Haha, believe it or not I did not translate that page, I just blindly harvested the code… So i missed that warning! :]

 

So, can you provide a simple one liner to isolate specific PathKinds? Does such a beast exist? I know that the following is incorrect as there is “no such element”, I am just using it as an example of what I was looking for:

app.activeDocument.pathItems.PathKind.CLIPPINGPATH.removeAll();

 

The best that I have been able to find has been variations on the following:

var myPath = activeDocument.pathItems;   
    for (n = myPath.length-1; n>-1; n--)   
    { aP = myPath[n];   
    if(aP.kind == "PathKind.CLIPPINGPATH" ) { aP.remove() }
    }
var myPath2 = activeDocument.pathItems;   
    for (n = myPath2.length-1; n>-1; n--)   
    { aP2 = myPath2[n];   
    if(aP2.kind == "PathKind.NORMALPATH" ) { aP2.remove() }
    }
var myPath3 = activeDocument.pathItems;   
    for (n = myPath3.length-1; n>-1; n--)   
    { aP3 = myPath3[n];   
    if(aP3.kind == "PathKind.WORKPATH" ) { aP3.remove() }
    }

 

Or different but same:

//https://forums.adobe.com/message/10238001#10238001    
for (var i = 0; i < activeDocument.pathItems.length; i++)  
	if (activeDocument.pathItems[i].kind == PathKind.CLIPPINGPATH)  
		{  
		activeDocument.pathItems[i].remove();  
		break;  
		}

for (var j = 0; j < activeDocument.pathItems.length; j++)  
	if (activeDocument.pathItems[i].kind == PathKind.NORMALPATH)  
		{  
		activeDocument.pathItems[i].remove();  
		break;  
		}

for (var k = 0; k < activeDocument.pathItems.length; k++)  
	if (activeDocument.pathItems[i].kind == PathKind.WORKPATH)  
		{  
		activeDocument.pathItems[i].remove();  
		break;  
		}

 

The problem I am having is incorporating them into the script… They work fine by themselves, however I have not been able to work them into the script without breaking it.

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 ,
Oct 15, 2018 Oct 15, 2018

Copy link to clipboard

Copied

one important note:

loop backwards

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 ,
Oct 15, 2018 Oct 15, 2018

Copy link to clipboard

Copied

I’m sure that will mean something to me someday! Baby steps… :]

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 22, 2020 Apr 22, 2020

Copy link to clipboard

Copied

Discussion of how to safely remove various PathKind's without removing shape layer paths continued with a correct result here:

 

deleting ps-paths automatically

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 22, 2020 Apr 22, 2020

Copy link to clipboard

Copied

I have updated the modifications that I made back in 2018 with better code and some more options... This is intended as a general-purpose interactive "housekeeping" script to remove/clean common file attributes. Many thanks to those that have directly and indirectly helped this learning project!

 

2021 EDIT: Old code removed and updated in a new post!

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 03, 2021 Jan 03, 2021

Copy link to clipboard

Copied

2023 UPDATE:

2023.png

 

 

// Bulk Remove All Selected Items 2023.jsx
// Stephen Marsh
// Version: 28th January 2023

/*
Based on:
Free script: Remove Selected
Originally created by Dale R, for public and commercial use, 2018
https://community.adobe.com/t5/photoshop-ecosystem-discussions/free-script-remove-selected/td-p/10104624#U11724396
*/

#target photoshop

if (app.documents.length !== 0) {

    app.activeDocument.suspendHistory('Bulk Remove All Selected Items (2023)', 'main()');

    function main() {
        // Window variables
        var win = new Window('dialog', 'Bulk Remove All Selected Items (2023)');
        win.preferredSize = [50, 100];
        win.alignChildren = "left"; // align checkboxes to left

        // Create checkbox group 1
        var check_group1 = win.add("panel", undefined, "Remove Paths:");
        check_group1.alignChildren = "left";
        var check04 = check_group1.add("CheckBox { text: 'All Clipping Paths', value: true}");
        var check05 = check_group1.add("CheckBox { text: 'All Normal Paths', value: true}");
        var check06 = check_group1.add("CheckBox { text: 'All Work Paths', value: true}");

        // Create checkbox group 2
        var check_group2 = win.add("panel", undefined, "Remove Channels:");
        check_group2.alignChildren = "left";
        var check03 = check_group2.add("CheckBox { text: 'All Alpha Channels', value: true}");
        var check12 = check_group2.add("CheckBox { text: 'All Spot Channels', value: true}");

        // Create checkbox group 4
        var check_group4 = win.add("panel", undefined, "Remove Guides:");
        check_group4.alignChildren = "left";
        var check14 = check_group4.add("CheckBox { text: 'All Horizontal Guides', value: true}");
        var check15 = check_group4.add("CheckBox { text: 'All Vertical Guides', value: true}");

        // Create checkbox group 3
        var check_group3 = win.add("panel", undefined, "Remove Other Items:");
        check_group3.alignChildren = "left";
        var check01 = check_group3.add("CheckBox { text: 'All Layer Comps', value: true}");
        var check02 = check_group3.add("CheckBox { text: 'All Color Samplers', value: true}");
        var check17 = check_group3.add("CheckBox { text: 'All Notes', value: true}");
        var check07 = check_group3.add("CheckBox { text: 'All Empty Layers \&& Groups', value: true}");
        var check16 = check_group3.add("CheckBox { text: 'All Invisible Layers \&& Groups', value: true}");
        var check13 = check_group3.add("CheckBox { text: 'All History Snapshots', value: false}"); // disable
        var check11 = check_group3.add("CheckBox { text: 'All Metadata (New File)', value: false}"); // disable
        var check10 = check_group3.add("CheckBox { text: 'All Camera Raw Metadata', value: true}");
        var check08 = check_group3.add("CheckBox { text: 'All DocumentAncestors Metadata', value: true}");
        var check09 = check_group3.add("CheckBox { text: 'XMP Metadata', value: false}"); // disable

        // Create the panel
        var p = win.add('panel', undefined);
        p.alignment = "center";

        // Create Check All and Check None buttons
        var checkAll = p.add('button');
        checkAll.text = 'Check All';
        checkAll.alignment = ["fill","top"];
        checkAll.onClick = function () {
            toggleCheckBoxes(true);
        }
        var checkNone = p.add('button');
        checkNone.text = 'Check None';
        checkNone.alignment = ["fill","top"];
        checkNone.onClick = function () {
            toggleCheckBoxes(false);
        }

        // Create the OK and Cancel buttons
        var btn = p.add('button', undefined, 'OK');
        btn.alignment = ["fill", "top"];
        var btn2 = p.add("button", undefined, "Cancel");
        btn2.alignment = ["fill","top"];

        // Link actions to the UI elements
        btn.onClick = function () {
            win.close();

            if (check01.value === true) {
                // Remove all Layer Comps
                app.activeDocument.layerComps.removeAll();
            }
            if (check02.value === true) {
                // Remove all Color Samplers
                app.activeDocument.colorSamplers.removeAll();
            }
            if (check03.value === true) {
                // Remove all Alpha channels
                removeAllAlphaChannelsNotSpot();
            }
            if (check12.value === true) {
                // Remove all Spot channels
                removeAllSpotChannelsNotAlpha();
            }
            if (check04.value === true) {
                // Remove all Clipping Paths
                removeAllClipPaths();
            }
            if (check05.value === true) {
                // Remove all Normal Paths
                removeAllNormalPaths();
            }
            if (check06.value === true) {
                // Remove all Work Paths
                removeAllWorkPaths();
            }
            if (check07.value === true) {
                // Remove all empty layers/groups
                layrs2_DeleteEmptyLayers();
            }
            if (check08.value === true) {
                // Remove all photoshop:DocumentAncestors metadata
                deleteDocumentAncestorsMetadata();
            }
            if (check09.value === true) {
                // Remove all XMP metadata
                removeXMP();
            }
            if (check10.value === true) {
                // Remove all CRS metadata
                removeCRSmeta();
            }
            if (check11.value === true) {
                // Remove all metadata
                dupeRemoveMeta();
            }
            if (check13.value === true) {
                // Remove all history snapshots
                removeAllHistorySnapshots();
            }
            if (check14.value === true) {
                // Remove all horizontal guides
                removeAllHorizontalGuides();
            }
            if (check15.value === true) {
                // Remove all vertical guides
                removeAllVerticalGuides();
            }
            if (check16.value === true) {
                // Remove all invisible layers/sets
                removeInvisibleLayers(doc);
            }
            if (check17.value === true) {
                // Remove all notes
                removeNotes();
            }
        };

        ///// Functions - Start /////

        function toggleCheckBoxes(enabled) {
            check01.value = enabled;
            check02.value = enabled;
            check03.value = enabled;
            check04.value = enabled;
            check05.value = enabled;
            check06.value = enabled;
            check07.value = enabled;
            check08.value = enabled;
            check09.value = enabled;
            check10.value = enabled;
            check11.value = enabled;
            check12.value = enabled;
            check13.value = enabled;
            check14.value = enabled;
            check15.value = enabled;
            check16.value = enabled;
            check17.value = enabled;
        }

        function removeAllHorizontalGuides() {
            if (documents.length) {
                var count = app.activeDocument.guides.length;
                for (var a = count - 1; a >= 0; a--) {
                    if (app.activeDocument.guides[a].direction == Direction.HORIZONTAL) app.activeDocument.guides[a].remove();
                }
            }
        }

        function removeAllVerticalGuides() {
            if (documents.length) {
                var count = app.activeDocument.guides.length;
                for (var a = count - 1; a >= 0; a--) {
                    if (app.activeDocument.guides[a].direction == Direction.VERTICAL) app.activeDocument.guides[a].remove();
                }
            }
        }

        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()
                    }
                }
            }
        }

        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()
                    }
                }
            }
        }

        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()
                    }
                }
            }
        }

        function layrs2_DeleteEmptyLayers() {

            /*
            http://madebyvadim.com/layrs/
            */

            // ===========================
            // Delete Empty Layers
            // ===========================

            delEmptyLayers();
            function delEmptyLayers() {
                if (!documents.length) return;
                var layerInfo = getLayerInfo();
                for (var a in layerInfo) {//delete blank layers
                    if (layerInfo[a][2] == 'false') deleteLayerByID(Number(layerInfo[a][0]));
                }
                for (var z in layerInfo) {
                    if (layerInfo[z][2] == 'true') {//delete empty layerSets
                        selectLayerById(Number(layerInfo[z][0]));
                        if (activeDocument.activeLayer.layers.length == 0) deleteLayerByID(Number(layerInfo[z][0]));
                    }
                }
            };
            function deleteLayerByID(ID) {
                var desc = new ActionDescriptor();
                var ref = new ActionReference();
                ref.putIdentifier(charIDToTypeID('Lyr '), ID);
                desc.putReference(charIDToTypeID('null'), ref);
                executeAction(charIDToTypeID('Dlt '), desc, DialogModes.NO);
            };
            function selectLayerById(ID, add) {
                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);
                executeAction(charIDToTypeID('slct'), desc, DialogModes.NO);
            }
            function getLayerInfo() {
                var ref = new ActionReference();
                ref.putEnumerated(charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
                var count = executeActionGet(ref).getInteger(charIDToTypeID('NmbL')) + 1;
                var Names = [];
                try {
                    activeDocument.backgroundLayer;
                    var i = 0;
                } catch (e) { var i = 1; };
                for (i; i < count; i++) {
                    if (i == 0) continue;
                    ref = new ActionReference();
                    ref.putIndex(charIDToTypeID('Lyr '), i);
                    var desc = executeActionGet(ref);
                    var layerName = desc.getString(charIDToTypeID('Nm  '));
                    var Id = desc.getInteger(stringIDToTypeID('layerID'));
                    if (layerName.match(/^<\/Layer group/)) continue;
                    var layerType = typeIDToStringID(desc.getEnumerationValue(stringIDToTypeID('layerSection')));
                    var isLayerSet = (layerType == 'layerSectionContent') ? false : true;
                    var boundsDesc = desc.getObjectValue(stringIDToTypeID("bounds"));
                    if (boundsDesc.getUnitDoubleValue(stringIDToTypeID('right')) - boundsDesc.getUnitDoubleValue(stringIDToTypeID('left')) == 0) {
                        Names.push([[Id], [layerName], [isLayerSet]]);
                    }
                    if (isLayerSet) Names.push([[Id], [layerName], [isLayerSet]]);
                };
                return Names;
            };
        }

        function deleteDocumentAncestorsMetadata() {
            //forums.adobe.com/message/8456985#8456985
            whatApp = String(app.name); //String version of the app name
            if (whatApp.search("Photoshop") > 0) { //Check for photoshop specifically, or this will cause errors
                //Function Scrubs Document Ancestors from Files
                if (!documents.length) {
                    alert("There are no open documents. Please open a file to run this script.")
                    return;
                }
                if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
                // Begone foul Document Ancestors!
                xmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "DocumentAncestors");
                app.activeDocument.xmpMetadata.rawData = xmp.serialize();
            }
        }

        function removeXMP() {
            //community.adobe.com/t5/photoshop/script-to-remove-all-meta-data-from-the-photo/td-p/10400906
            if (!documents.length) return;
            if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
            var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
            XMPUtils.removeProperties(xmp, "", "", XMPConst.REMOVE_ALL_PROPERTIES);
            app.activeDocument.xmpMetadata.rawData = xmp.serialize();
        }

        function removeCRSmeta() {
            //community.adobe.com/t5/photoshop/remove-crs-metadata/td-p/10306935
            if (!documents.length) return;
            if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
            var xmp = new XMPMeta(app.activeDocument.xmpMetadata.rawData);
            XMPUtils.removeProperties(xmp, XMPConst.NS_CAMERA_RAW, "", XMPConst.REMOVE_ALL_PROPERTIES);
            app.activeDocument.xmpMetadata.rawData = xmp.serialize();
        }

        function dupeRemoveMeta() {

            /* Remove All Metadata & Retain Layers v2 - a brute force alternative to ExifTool
            https://community.adobe.com/t5/photoshop/script-to-remove-all-meta-data-from-the-photo/m-p/10400906
            Script to remove all metadata from the photo
            30th July 2020 Update */

            /* FLATTENED */
            if (app.activeDocument.activeLayer.isBackgroundLayer) {
                // alert('Flattened image...');
                // Call function to duplicate all layers
                DupeSelectedLayers.main = function () {
                    DupeSelectedLayers();
                };
                DupeSelectedLayers.main();
                alertMessage();
            }

            /* SINGLE (TRANSPARENT) LAYER BUG WORKAROUND */
            else if (app.activeDocument.layers.length === 1) {
                // alert('Single layer image...');
                // Set the original doc
                var sourceDoc = app.activeDocument;
                // Add a randomly named temp layer
                app.activeDocument.artLayers.add();
                app.activeDocument.activeLayer.name = "2563@361#47&-TEMP_LAYER";
                // Select all layers and layer groups/sets!
                selectAllLayers();
                // Call function to duplicate all layers
                DupeSelectedLayers.main = function () {
                    DupeSelectedLayers();
                };
                DupeSelectedLayers.main();
                // Select & remove temporary layer
                removeTempLayer(false);
                // Set the duplicated document
                var dupedDoc = app.activeDocument;
                // Switch back to the original doc
                app.activeDocument = sourceDoc;
                // Select & remove temporary layer
                removeTempLayer(false);
                // Set the duped doc as the active doc
                app.activeDocument = dupedDoc;
                alertMessage();
            }

            /* MULTIPLE LAYERS */
            else {
                // alert('Multiple layer image...');
                // Select all layers and layer groups/sets!
                selectAllLayers();
                // Call function to duplicate all layers
                DupeSelectedLayers.main = function () {
                    DupeSelectedLayers();
                };
                DupeSelectedLayers.main();
                alertMessage();
            }

            ///// START FUNCTIONS /////

            function selectAllLayers() {
                // https://feedback.photoshop.com/photoshop_family/topics/i-cant-record-sellect-all-layers-in-script-listener-and-in-actions
                var c2t = function (s) {
                    return app.charIDToTypeID(s);
                };

                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };

                var descriptor = new ActionDescriptor();
                var descriptor2 = new ActionDescriptor();
                var reference = new ActionReference();
                var reference2 = new ActionReference();

                reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                descriptor.putReference(c2t("null"), reference2);
                executeAction(s2t("selectAllLayers"), descriptor, DialogModes.NO);
                reference.putProperty(s2t("layer"), s2t("background"));
                descriptor2.putReference(c2t("null"), reference);
                descriptor2.putEnumerated(s2t("selectionModifier"), s2t("selectionModifierType"), s2t("addToSelection"));
                descriptor2.putBoolean(s2t("makeVisible"), false);
                try {
                    executeAction(s2t("select"), descriptor2, DialogModes.NO);
                } catch (e) { }
            }

            // Duplicate all selected layers to new document  
            function DupeSelectedLayers() {
                function step1(enabled, withDialog) {
                    if (enabled !== undefined && !enabled)
                        return;
                    cTID = function (s) {
                        return app.charIDToTypeID(s);
                    };
                    sTID = function (s) {
                        return app.stringIDToTypeID(s);
                    };
                    var origFilename = app.activeDocument.name.replace(/\.[^\.]+$/, ''); // Remove filename extension from original
                    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
                    var desc1 = new ActionDescriptor();
                    var ref1 = new ActionReference();
                    ref1.putClass(cTID('Dcmn'));
                    desc1.putReference(cTID('null'), ref1);
                    // Use the original document filename + suffix
                    desc1.putString(cTID('Nm  '), origFilename + "_NoMetadata");
                    // Use the original document filename, beware overwriting the original file and losing all metadata!
                    // desc1.putString(cTID('Nm  '), origFilename );               
                    var ref2 = new ActionReference();
                    ref2.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
                    desc1.putReference(cTID('Usng'), ref2);
                    desc1.putInteger(cTID('Vrsn'), 5);
                    executeAction(cTID('Mk  '), desc1, dialogMode);
                }

                step1();
            }

            function removeTempLayer(makeVisible) {
                // Select & remove temporary layer
                var c2t = function (s) {
                    return app.charIDToTypeID(s);
                };
                var s2t = function (s) {
                    return app.stringIDToTypeID(s);
                };
                var descriptor = new ActionDescriptor();
                var list = new ActionList();
                var reference = new ActionReference();
                reference.putName(s2t("layer"), "2563@361#47&-TEMP_LAYER");
                descriptor.putReference(c2t("null"), reference);
                descriptor.putBoolean(s2t("makeVisible"), makeVisible);
                list.putInteger(3);
                descriptor.putList(s2t("layerID"), list);
                executeAction(s2t("select"), descriptor, DialogModes.NO);
                app.activeDocument.activeLayer.remove();
            }

            function alertMessage() {
                alert('File duplicated to remove metadata with "_NoMetadata" suffix added to the filename for safety.' + '\r' + 'Note: guides, color samplers, alpha channels, paths and other common document additions have not been copied.');

            }

            ///// FINISH FUNCTIONS /////
        }

        function removeAllAlphaChannelsNotSpot() {
            // https://community.adobe.com/t5/photoshop/remove-alpha-channel-during-a-batch/m-p/11285697?page=1#M347558
            var myChannel = app.activeDocument.channels;
            for (n = myChannel.length - 1; n >= 0; n--) {
                var value = myChannel[n];
                aC = myChannel[n];
                if (aC.kind == "ChannelType.MASKEDAREA") {
                    aC.remove()
                }
            }
        }

        function removeAllSpotChannelsNotAlpha() {
            // https://community.adobe.com/t5/photoshop/remove-alpha-channel-during-a-batch/m-p/11285697?page=1#M347558
            var myChannel = app.activeDocument.channels;
            for (n = myChannel.length - 1; n >= 0; n--) {
                var value = myChannel[n];
                aC = myChannel[n];
                if (aC.kind == "ChannelType.SPOTCOLOR") {
                    aC.remove()
                }
            }
        }

        function removeAllHistorySnapshots() {
            /* https://www.photoshopgurus.com/forum/threads/how-to-delete-all-history-states-not-history-or-other-solution-to-a-master-macro.55456/#post-1533719707 */
            var doc = app.activeDocument;
            var hs = doc.historyStates;
            for (var a = hs.length - 1; a >= 0; --a) {
                if (hs[a].snapshot) {
                    doc.activeHistoryState = hs[a];
                    delHist();
                }
            }
            function delHist() {
                var desc20 = new ActionDescriptor();
                var ref23 = new ActionReference();
                ref23.putProperty(charIDToTypeID('HstS'), charIDToTypeID('CrnH'));
                desc20.putReference(charIDToTypeID('null'), ref23);
                executeAction(charIDToTypeID('Dlt '), desc20, DialogModes.NO);
            }
        }

        /* http://creativetuts.com/photoshop/photoshop-script-code-snippet-archive/ */
        var doc = app.activeDocument;
        function removeInvisibleLayers(doc) {
            for (var i = doc.artLayers.length - 1; 0 <= i; i--) {
                try {
                    if (!doc.artLayers[i].visible) {
                        doc.artLayers[i].remove();
                    }
                }
                catch (e) {
                }
            }
            for (var j = doc.layerSets.length - 1; 0 <= j; j--) {
                removeInvisibleLayers(doc.layerSets[j]);
            }
        }

        function removeNotes() {
            executeAction(stringIDToTypeID("deleteAllAnnot"), new ActionDescriptor(), DialogModes.NO);
        }

        ///// Functions - Finish /////

        win.center();
        win.show();
    }

} else {
    alert('You must have a document open!');
}

 

 CHANGE LOG: 

  • 22nd April 2020 – Initial release
  • 23rd April 2020 – Added All Camera Raw Metadata, changed All EXIF Metadata to XMP Metadata to more accurately set expectations of the results
  • 26 April 2020 – Added a check/alert if no document is open when running the script, added a new option All Metadata (New File) to remove the maximum amount of metadata by creating a new document by layer duplication (not document duplication, which copies the metadata)
  • 14th July 2020 – Added separate options to remove Alpha channels and Spot channels (rather than All Alpha/Spot channels as a single option)
  • 22nd July 2020 – Updated refined code for the All Metadata (New File) option
  • 30th July 2020 – Removed redundant code in the All Metadata (New File) option, a general tidy-up!
  • 4th January 2021 – Added an option to remove All History Snapshots and refined the guide options by removing redundant entries
  • 5th January 2021 – Added an option to remove All Invisible Layers/Sets (which may require the use of the option to remove all empty layers in certain circumstances)
  • 27th January 2023 – Added buttons to Check All or Uncheck All checkboxes. Replaced the path removal functions with updated, refined code
  • 28th January 2023 – Added an option to remove all notes/annotations

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
LEGEND ,
Jan 04, 2021 Jan 04, 2021

Copy link to clipboard

Copied

If I'm right creating new document to remove all metadata is redunant if you can do this on active one:

 

if (!ExternalObject.AdobeXMPScript)
	ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript')
activeDocument.xmpMetadata.rawData = new XMPMeta().serialize()

 

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 04, 2021 Jan 04, 2021

Copy link to clipboard

Copied

Hi Kukurykus AFAIK it is only possile to remove XMP metadata through scripting, which may still leave unwanted metadata in certain cases, such as EXIF or camera related data. This script offers both methods. More here:

 

Script to remove all meta data from the photo

 

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
New Here ,
Feb 22, 2021 Feb 22, 2021

Copy link to clipboard

Copied

Is there a way that you can run this script (or a version of it) within an action and selecting certain items but without being promted with the dialogue box every time for each document? I would find it useful to create an action using this script and be able to batch process it over a whole folder of documents that all need paths and alpha channels removed. Thanks!

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