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

Per Layer Metadata: How do I delete an XMP Object from a layer?

New Here ,
Jun 12, 2015 Jun 12, 2015

The only way I have found so far is to "reset" the XMP object by assigning an empty one :

var emptyXMP = new XMPMeta();

app.activeDocument.activeLayer.xmpMetadata.rawData = emptyXMP.serialize();

TOPICS
Actions and scripting
1.3K
Translate
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
Advocate ,
Jun 15, 2015 Jun 15, 2015

Hi,

I have the following snip in my personal library - I'm afraid I can't add any context nor credits since I got it from ps-scripts.com (currently offline - can't find the original page in the archive.org snaps).

Hope this helps anyway, see Pslib.deleteXmpProperty():

// layer metadata editor

// original source:

// http://www.ps-scripts.com/bb/viewtopic.php?f=9&t=2644&sid=95623758e9e6fad92a896b1486ae9af4

#target photoshop

// #############  PER-LAYER METADATA FUNCTIONS

Pslib = function() {};

// define default namespace

Pslib.XMPNAMESPACE = "http://custom/";

Pslib.XMPNAMESPACEPREFIX = "cstm:";

try {

    // load library

    if (!ExternalObject.AdobeXMPScript) {

        ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');

    }

    // register custom namespace

    XMPMeta.registerNamespace(Pslib.XMPNAMESPACE, Pslib.XMPNAMESPACEPREFIX);

    } catch (e) {

    // if ExternalObject.AdobeXMPScript not present, hardcode the namespace to exif

    Pslib.XMPNAMESPACE = "http://ns.adobe.com/exif/1.0/";

    }

// load XMP

Pslib.loadXMPLibrary = function() {

    if (!ExternalObject.AdobeXMPScript) {

        try {

            if ($.level) $.writeln("Loading XMP Script Library");

            ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');

            return true;

        } catch (e) {

            if ($.level) $.writeln("Error loading XMP Script Library\n" + e);

            return false;

        }

    }

    return true;

    };

// unload XMP

Pslib.unloadXMPLibrary = function() {

    if (ExternalObject.AdobeXMPScript) {

        try {

            if ($.level) $.writeln("Unloading XMP Script Library");

            ExternalObject.AdobeXMPScript.unload();

            ExternalObject.AdobeXMPScript = undefined;

            return true;

        } catch (e) {

            if ($.level) $.writeln("Error unloading XMP Script Library\n" + e);

            return false;

        }

    }

    };

// get layer's existing XMP if present

Pslib.getXmp = function(layer, createNew) {

    var layer = (layer == undefined ? app.activeDocument.activeLayer : layer);

    var createNew = (createNew == undefined ? false : createNew);

    var xmp;

    // if library loads without problem, proceed to get the layer's xmpMetadata

    if (Pslib.loadXMPLibrary()) {

        try {

            if ($.level) $.writeln("Attempting to get metadata for layer \"" + layer.name + "\"");

            xmp = new XMPMeta(layer.xmpMetadata.rawData);

        } catch (e) {

            if ($.level) $.writeln("Metadata could not be found for layer \"" + layer.name + "\"" + (createNew ? "\nCreating new XMP object." : ""));

            if (createNew) xmp = new XMPMeta();

        }

        return xmp;

    } else {

        return xmp;

    }

    };

// get property: returns a string

Pslib.getXmpProperty = function(layer, property) {

    // make sure XMP lib stuff is available

    if (Pslib.loadXMPLibrary()) {

        var layer = layer == undefined ? app.activeDocument.activeLayer : layer;

        var value;

        var xmp;

        // make sure we're not working with a background layer

        if (layer.isBackgroundLayer) {

            if ($.level) $.writeln("Metadata cannot exist on a background layer, so it cannot be accessed.");

            return null;

        }

        // access metadata

        try {

            xmp = new XMPMeta(layer.xmpMetadata.rawData);

            value = xmp.getProperty(Pslib.XMPNAMESPACE, property)

            // unload library

            //   Pslib.unloadXMPLibrary();

            return value;

        } catch (e) {

            if ($.level) $.writeln("XMP metadata could not be found for layer \"" + layer.name + "\"");

            //   xmp = new XMPMeta();

            return null

        }

    } else {

        return null;

    }

    };

// delete specific property

Pslib.deleteXmpProperty = function(layer, property) {

    // load library

    if (Pslib.loadXMPLibrary()) {

        var layer = layer == undefined ? app.activeDocument.activeLayer : layer;

        var xmp = Pslib.getXmp(layer);

        try {

            xmp.deleteProperty(Pslib.XMPNAMESPACE, property);

            layer.xmpMetadata.rawData = xmp.serialize();

            return true;

        } catch (e) {

            if ($.level) $.writeln("Metadata property could not be deleted from layer \"" + layer.name + "\"");

            //xmp = new XMPMeta();

            return false;

        }

    } else {

        return false;

    }

    };

// set multiple properties

// expects a two-dimensional array

Pslib.setXmpProperties = function(layer, propertiesArray) {

    // make sure XMP lib stuff is available

    if (Pslib.loadXMPLibrary()) {

        var layer = layer == undefined ? app.activeDocument.activeLayer : layer;

        var prop;

        var val;

        var xmp;

        // make sure we're not working with a background layer

        if (layer.isBackgroundLayer) {

            if ($.level) $.writeln("XMP Metadata cannot be placed on a background layer. Aborting.");

            return false;

        }

        // access metadata

        try {

            xmp = new XMPMeta(layer.xmpMetadata.rawData);

            if ($.level) $.writeln("XMP Metadata successfully fetched from layer \"" + layer.name + "\"");

        } catch (e) {

            if ($.level) $.writeln("XMP metadata could not be found for layer \"" + layer.name + "\".\nCreating new XMP metadata container.");

            xmp = new XMPMeta();

        }

        // loop through array properties and assign them

        if ($.level) $.writeln("\nLooping through properties...");

        for (var i = 0; i < propertiesArray.length; i++) {

            prop = propertiesArray[0];

            val = propertiesArray[1];

            // modify metadata

            try {

                var propertyExists = xmp.doesPropertyExist(Pslib.XMPNAMESPACE, prop);

                // add new property if not found

                if (!propertyExists) {

                    xmp.setProperty(Pslib.XMPNAMESPACE, prop, val);

                    if ($.level) $.writeln("\tadding [" + prop + ": " + val + "]  " + typeof val);

                }

                // if property found and value different, update

                else if (propertyExists && xmp.getProperty(Pslib.XMPNAMESPACE, prop).toString() != val.toString()) {

                    xmp.setProperty(Pslib.XMPNAMESPACE, prop, val);

                    if ($.level) $.writeln("\tupdating [" + prop + ": " + val + "]  " + typeof val);

                } else {

                    if ($.level) $.writeln("\tno change to existing property [" + prop + ": " + val + "]  " + typeof val);

                }

            } catch (e) {

                var msg = "Could not place metadata property on provided layer.\n[" + prop + ": " + val + +"]  " + typeof val + "\n" + e;

                if ($.level) $.writeln(msg);

                else alert(msg);

                return false;

            }

        }

        // applly and serialize

        layer.xmpMetadata.rawData = xmp.serialize();

        if ($.level) $.writeln("Provided properties were successfully added to object \"" + layer.name + "\"");

        // unload library

        //   Pslib.unloadXMPLibrary();

        return true;

    } else {

        return false;

    }

    };

// clear XMP : current workaround is to replace current data by empty data

// this is problematic if you actually want to strip the layer from its metadata object entirely

Pslib.clearXmp = function(layer) {

    if (Pslib.loadXMPLibrary()) {

        var layer = layer == undefined ? app.activeDocument.activeLayer : layer;

        // if metadata not found, return

        try {

            var xmp = new XMPMeta(layer.xmpMetadata.rawData);

        } catch (e) {

            //if($.level) $.writeln(msg + "\n" + e);

            return true;

        }

        // if metadata found, replace by empty version

        var emptyXmp = new XMPMeta();

        layer.xmpMetadata.rawData = emptyXmp.serialize();

        //   Pslib.unloadXMPLibrary();

        return true;

    } else {

        return false;

    }

    };

// save metadata to XML file

Pslib.exportLayerMetadata = function(layer, path, alertMsg) {

    if (Pslib.loadXMPLibrary()) {

        var xmp;

        // verify that xmp data is available

        try {

            var xmp = layer.xmpMetadata.rawData.toString();

            //

            if (alertMsg) alert(xmp);

            //

        } catch (e) {

            var msg = "";

            if (e.message.match("missing") != null) {

                msg += "There doesn't seem to be any metadata attached to layer \"" + layer.name + "\"";

            }

            if ($.level) $.writeln(msg + "\n" + e);

            else alert(msg + "\n" + e);

            return false;

        }

        var path = path == undefined ? File.saveDialog() : path;

        if (path != null) {

            var file = new File(path);

            if (file.exists) {

                if ($.level) $.writeln("\nFile already present. Prompting user for permission to replace.");

                // if file exists, present the user with the option to replace it

                if (confirm("Do you wish to overwrite this file?\n\n" + file.fsName, true, "Replace file?")) {

                    try {

                        if ($.level) $.writeln("Removing file:\n" + file.fsName);

                        file.remove();

                    } catch (e) {

                        if ($.level) $.writeln("\nCould not remove file. Please verify that it is not open by a different process.");

                        return false;

                    }

                } else {

                    if ($.level) $.writeln("User opted not to replace the file.");

                    return false;

                }

            }

            file.encoding = "UTF-8";

            try {

                file.open("w");

                file.write(xmp);

                file.close();

            } catch (e) {

                var msg = "";

                if ($.level) $.writeln("Unable to write to file.\n" + msg + "\n" + e);

                else alert("Unable to write to file.\n" + msg + "\n" + e);

                return false;

            }

            file.close();

        }

        //   Pslib.unloadXMPLibrary();

        return true;

    } else {

        return false;

    }

    };

// app functions

function Main() {

    // prepare XMP container

    var XMPObj = null;

    // build dialog window

    var win = new Window('dialog', "Layer Metadata Editor");

    win.alignChildren = 'fill';

    var maingroup = win.add('group');

    maingroup.orientation = "column";

    maingroup.alignChildren = 'fill';

    var propxmp = maingroup.add('group');

    propxmp.orientation = "column";

    propxmp.alignChildren = 'fill';

    var propertiesPanel = propxmp.add('panel', undefined, "Individual Properties");

    propertiesPanel.alignChildren = 'left';

    var propertyGroup = propertiesPanel.add('group');

    propertyGroup.add('statictext', undefined, "Property:");

    var property = propertyGroup.add('edittext', undefined, "");

    property.characters = 20;

    propertyGroup.add('statictext', undefined, "Value:");

    var propertyValue = propertyGroup.add('edittext', undefined, "");

    propertyValue.characters = 20;

    var propertyDebug = propertiesPanel.add('statictext', undefined, "");

    propertyDebug.characters = 75;

    propertyDebug.enabled = false;

    var dataButtonsGroup = propertiesPanel.add('group');

    var getValue = dataButtonsGroup.add('button', undefined, "Get");

    var setValue = dataButtonsGroup.add('button', undefined, "Set");

    var removeProperty = dataButtonsGroup.add('button', undefined, "Remove");

    var xmpDisplay = maingroup.add('group');

    xmpDisplay.alignChildren = 'fill';

    var xmpDisplayPanel = xmpDisplay.add('panel', undefined, "XMPMeta Object");

    xmpDisplayPanel.alignChildren = 'left';

    var xmpDisplayText = xmpDisplayPanel.add("edittext", undefined, XMPObj);

    xmpDisplayText.characters = 70;

    xmpDisplayText.multiline = true;

    xmpDisplayText.preferredSize.height = 300;

    var xmpDebug = xmpDisplayPanel.add('statictext', undefined, "");

    xmpDebug.characters = 75;

    xmpDebug.enabled = false;

    var xmpButtonsGroup = xmpDisplayPanel.add('group');

    var addXMPObject = xmpButtonsGroup.add('button', undefined, "Add");

    var getXMPObject = xmpButtonsGroup.add('button', undefined, "Get");

    var saveToXML = xmpButtonsGroup.add('button', undefined, "Save to XML");

    saveToXML.enabled = exportXML;

    saveToXML.helpTip = "You should save your document before using this feature.";

    var removeXMPObject = xmpButtonsGroup.add('button', undefined, "Remove");

    //  

    // individual properties callbacks

    //

    // get value for specified property

    getValue.onClick = function() {

        var prop = property.text

        var val = propertyValue.text;

        if (prop != "") {

            if (!layerObject.isBackgroundLayer) {

                // check for existing XMP object

                XMPObj = Pslib.getXmp(layerObject);

                if (XMPObj != null) {

                    var data = Pslib.getXmpProperty(layerObject, prop);

                    propertyValue.text = data != undefined ? data : propertyValue.text;

                    if (data == undefined) propertyDebug.text = "[GET PROPERTY: Property not found]";

                    XMPObj = new XMPMeta(layerObject.xmpMetadata.rawData);

                    xmpDisplayText.text = XMPObj.serialize();

                } else {

                    var msg = "[GET PROPERTY: No XMP object found on layer]";

                    xmpDebug.text = msg;

                    xmpDisplayText.text = msg;

                }

            } else {

                var msg = "[GET PROPERTY: A background layer cannot contain an XMP object]";

                xmpDebug.text = msg;

                xmpDisplayText.text = msg;

            }

        } else {

            var msg = "[GET PROPERTY: Please enter a property name]";

            propertyDebug.text = msg;

            xmpDisplayText.text = msg;

        }

    };

    // set value for specified property -- creates property if not found

    setValue.onClick = function() {

        if (property.text != "" && propertyValue.text != "" && propertyValue.text != "[INVALID]") {

            if (!layerObject.isBackgroundLayer) {

                XMPObj = Pslib.getXmp(layerObject);

                if (XMPObj != null) {

                    var propertyExists;

                    var testXmp;

                    try {

                        testXmp = new XMPMeta(layerObject.xmpMetadata.rawData);

                        propertyExists = testXmp.doesPropertyExist(Pslib.XMPNAMESPACE, property.text);

                    } catch (e) {

                        exists = false;

                    }

                    if (Pslib.setXmpProperties(layerObject, [

                            [property.text, propertyValue.text]

                        ])) {

                        propertyDebug.text = "[ADD PROPERTY: Property " + (propertyExists ? "updated" : "added") + " successfully]";

                        XMPObj = new XMPMeta(layerObject.xmpMetadata.rawData);

                        xmpDisplayText.text = XMPObj.serialize();

                    } else {

                        var msg = "[ADD PROPERTY: Error adding property]";

                        propertyDebug.text = msg;

                        xmpDisplayText.text = msg;

                    }

                } else {

                    var msg = "[ADD PROPERTY: XMP Object not found.]";

                    propertyDebug.text = msg;

                    xmpDisplayText.text = msg;

                }

            } else {

                var msg = "[ADD PROPERTY: A background layer cannot contain metadata]";

                xmpDebug.text = msg;

                xmpDisplayText.text = msg;

            }

        } else {

            var msg = "[ADD PROPERTY: Provided value is either invalid or empty]";

            propertyDebug.text = msg;

            xmpDisplayText.text = msg;

        }

    };

    // remove specified property

    removeProperty.onClick = function() {

        if (property.text != "") {

            if (!layerObject.isBackgroundLayer) {

                if (Pslib.deleteXmpProperty(layerObject, property.text)) {

                    propertyDebug.text = "[REMOVE PROPERTY: Property removed successfully]";

                    XMPObj = new XMPMeta(layerObject.xmpMetadata.rawData);

                    xmpDisplayText.text = XMPObj.serialize();

                } else {

                    var msg = "[REMOVE PROPERTY: Error removing property]";

                    propertyDebug.text = msg;

                    xmpDisplayText.text = msg;

                }

            } else {

                var msg = "[REMOVE PROPERTY: A background layer cannot contain an XMP object]";

                xmpDebug.text = msg;

                xmpDisplayText.text = msg;

            }

        } else {

            var msg = "[REMOVE PROPERTY: Please enter a property name]";

            xmpDebug.text = msg;

            xmpDisplayText.text = msg;

        }

    };

    //

    // XMP object callbacks

    //

    // add XMP object to provided layer

    addXMPObject.onClick = function() {

        if (!layerObject.isBackgroundLayer) {

            var hasXMP = Pslib.getXmp(layerObject);

            // if layer already has XMP, confirm with user before replacing it

            if (hasXMP != null) {

                // confirm replacement of current XMP object

                if (confirm("Do you wish to replace the existing XMP object by a new one?")) {

                    XMPObj = new XMPMeta();

                    layerObject.xmpMetadata.rawData = XMPObj.serialize();

                    xmpDisplayText.text = XMPObj.serialize();

                    xmpDebug.text = "[ADD XMP: Current layer XMP object successfully replaced by empty XMP object]";

                } else {

                    xmpDebug.text = "[ADD XMP: Current layer XMP object preserved]";

                    XMPObj = new XMPMeta(layerObject.xmpMetadata.rawData);

                    xmpDisplayText.text = XMPObj.serialize();

                }

            }

            // if layer does NOT have XMP

            else {

                XMPObj = new XMPMeta();

                layerObject.xmpMetadata.rawData = XMPObj.serialize();

                xmpDisplayText.text = XMPObj.serialize();

                xmpDebug.text = "[ADD XMP: XMP object successfully added to layer]";

            }

        } else {

            var msg = "[ADD XMP: Cannot add XMP object to a background layer]";

            xmpDebug.text = msg;

            xmpDisplayText.text = msg;

        }

    };

    // get XMP object

    getXMPObject.onClick = function() {

        if (!layerObject.isBackgroundLayer) {

            // get existing XMP Object

            if (Pslib.getXmp(layerObject)) {

                xmpDebug.text = "[GET XMP: Existing XMP object successfully harvested from layer]";

                XMPObj = new XMPMeta(layerObject.xmpMetadata.rawData);

                xmpDisplayText.text = XMPObj.serialize();

            } else {

                var msg = "[GET XMP: No XMP object found on layer]";

                xmpDebug.text = msg;

                xmpDisplayText.text = msg;

            }

        } else {

            var msg = "[GET XMP: A background layer cannot contain an XMP object]";

            xmpDebug.text = msg;

            xmpDisplayText.text = msg;

        }

    };

    // save XMP object to XML file

    saveToXML.onClick = function() {

        if (!layerObject.isBackgroundLayer) {

            if (Pslib.exportLayerMetadata(layerObject, doc.path + "/" + doc.name + "_" + layerObject.name + ".xml", false)) {

                xmpDebug.text = "[SAVE XML: XMP object successfully exported to XML file]";

                XMPObj = new XMPMeta(layerObject.xmpMetadata.rawData);

                xmpDisplayText.text = XMPObj.serialize();

            } else {

                var msg = "[SAVE XML: No XMP object found on layer]";

                xmpDebug.text = msg;

                xmpDisplayText.text = msg;

            }

        } else {

            var msg = "[SAVE XML: A background layer cannot contain an XMP object]";

            xmpDebug.text = msg;

            xmpDisplayText.text = msg;

        }

    };

    // remove XMP object from layer (replaces the existing XMP by an empty one)

    removeXMPObject.onClick = function() {

        if (!layerObject.isBackgroundLayer) {

            var testXmp;

            var clearXMP = Pslib.clearXmp(layerObject);

            if (clearXMP) {

                // need one more try/catch block here, because Pslib.clearXmp also returns true when there is no XMP object attached to the layer

                try {

                    //testXmp = new XMPMeta( layerObject.xmpMetadata.rawData );

                    XMPObj = new XMPMeta(layerObject.xmpMetadata.rawData);

                    layerObject.xmpMetadata.rawData = XMPObj.serialize();

                    xmpDisplayText.text = XMPObj.serialize();

                    xmpDebug.text = "[REMOVE XMP: layer XMP object successfully replaced by empty XMP object]";

                } catch (e) {

                    var msg = "[REMOVE XMP: No XMP object found on layer]";

                    xmpDisplayText.text = msg;

                    xmpDebug.text = msg;

                }

            } else {

                var msg = "[REMOVE XMP: Error removing XMP object from layer]";

                xmpDebug.text = msg;

                xmpDisplayText.text = msg;

            }

        } else {

            var msg = "[REMOVE XMP: A background layer cannot contain metadata]";

            xmpDebug.text = msg;

            xmpDisplayText.text = msg;

        }

    };

    // load XMP object

    getXMPObject.onClick();

    // show dialog

    win.center();

    win.show();

    };

//

// Main app execution

//

if (app.documents.length) {

    var doc = app.activeDocument;

    var layerObject = doc.activeLayer;

    var exportXML;

    // this is to determine where to save the XML file

    try {

        var docpath = doc.path;

        exportXML = true;

    } catch (e) {

        exportXML = false;

    }

    Main();

    } else {

    alert("No available document!");

    }

Davide Barranca

---

www.davidebarranca.com

www.cs-extensions.com

Translate
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 ,
Jun 16, 2015 Jun 16, 2015
LATEST

Thanks Davide

I'm successful in deleting the properties per say -- what I'm looking for is how to remove the XMP object that is attached to the layer once you've serialized rawdata to it. The .clearXmp function is also using a workaround. I don't see anything anywere in the Adobe documentation about going layer.xmpMetadata = null or layer.xmpMetadata = undefined (or something along those lines).

Translate
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