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

Add Support for IPTC/PLUS Coalition - Generative AI/ML training Metadata

Community Expert ,
Aug 18, 2024 Aug 18, 2024

Copy link to clipboard

Copied

I believe that it would be a good thing to add native File Info support for the following to Adobe products via File Info and Metadata Templates:

 

https://iptc.org/news/exclude-images-from-generative-ai-iptc-photo-metadata-standard-2023-1/

 

Caveats: Not for Adobe Stock and this requires that the embedded metadata is not stripped out  :]

Idea No status
TOPICS
macOS , Web , Windows

Views

417

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
12 Comments
Community Expert ,
Aug 19, 2024 Aug 19, 2024

Copy link to clipboard

Copied

Some example ExifTool (12.67) commands:

 

 

exiftool -XMP-plus:DataMining='https://ns.useplus.org/ldf/vocab/DMI-UNSPECIFIED' 'pathToFileOrFolder'

exiftool -XMP-plus:DataMining='https://ns.useplus.org/ldf/vocab/DMI-ALLOWED' 'pathToFileOrFolder'

exiftool -XMP-plus:DataMining='https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-AIMLTRAINING' 'pathToFileOrFolder'

exiftool -XMP-plus:DataMining='https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-GENAIMLTRAINING' 'pathToFileOrFolder'

exiftool -XMP-plus:DataMining='https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING' 'pathToFileOrFolder'

exiftool -XMP-plus:DataMining='https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED' 'pathToFileOrFolder'

exiftool -XMP-plus:DataMining= 'pathToFileOrFolder'

 

 

(Windows users would swap out the single-straight quotes ' for double-straight quotes ")

 

I'll need to see if it is possible to script Photoshop or Bridge to add such metadata...

 

Of course, this depends on machine learning companies to support and honour such metadata entries excluding them from training their services on your data (yeah, I know).

 

Votes

Translate

Translate

Report

Report
Community Expert ,
Aug 19, 2024 Aug 19, 2024

Copy link to clipboard

Copied

This example Photoshop script will clear and add the AI/ML data mining "prohibited" metadata entry to an open document.

 

/*
Add IPTC PLUS Generative AI-ML Metadata to Open Doc.jsx
v1.0 - 19th August 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-ideas/add-support-for-iptc-plus-coalition-generative-ai-ml-training-metadata/idi-p/14808232

https://iptc.org/news/exclude-images-from-generative-ai-iptc-photo-metadata-standard-2023-1/
https://ns.useplus.org/LDF/ldf-XMPSpecification#DataMining

Example Controlled Vocabulary Entries:

https://ns.useplus.org/ldf/vocab/DMI-UNSPECIFIED
https://ns.useplus.org/ldf/vocab/DMI-ALLOWED
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-AIMLTRAINING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-GENAIMLTRAINING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED
*/

#target photoshop

if (app.documents.length) {
    var contVocabEntry = "https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED";
    if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
    var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);
    xmp.deleteProperty("http://ns.useplus.org/ldf/xmp/1.0/", "DataMining");
    xmp.setProperty("http://ns.useplus.org/ldf/xmp/1.0/", "DataMining", contVocabEntry);
    app.activeDocument.xmpMetadata.rawData = xmp.serialize();
} else {
    alert("A document must be open to run this script!");
}

 

Here it is for selected files in Adobe Bridge:

 

/*
Add IPTC PLUS Generative AI-ML Metadata from Bridge Tools.jsx
v1.0 - 19th August 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-ideas/add-support-for-iptc-plus-coalition-generative-ai-ml-training-metadata/idi-p/14808232

https://ns.useplus.org/LDF/ldf-XMPSpecification#DataMining
https://iptc.org/news/exclude-images-from-generative-ai-iptc-photo-metadata-standard-2023-1/

Example Controlled Vocabulary Entries:

https://ns.useplus.org/ldf/vocab/DMI-UNSPECIFIED
https://ns.useplus.org/ldf/vocab/DMI-ALLOWED
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-AIMLTRAINING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-GENAIMLTRAINING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED
*/

#target bridge

addAIMLmeta = {};

addAIMLmeta.execute = function () {

    var contVocabEntry = "https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED";

    var sels = app.document.selections;
    for (var i = 0; i < sels.length; i++) {
        var md = sels[i].synchronousMetadata;
        // Clear the metadata before writing?
        md.namespace = "http://ns.useplus.org/ldf/xmp/1.0/";
        md.DataMining = contVocabEntry;
    }
}

if (BridgeTalk.appName == "bridge") {
    var menu = MenuElement.create("command", "Add PLUS Generative AI-ML Metadata", "at the end of Tools");
    menu.onSelect = addAIMLmeta.execute;
}

 

 

Votes

Translate

Translate

Report

Report
Community Expert ,
Sep 26, 2024 Sep 26, 2024

Copy link to clipboard

Copied

A GUI version for Photoshop:

 

2024-09-26_22-47-42.png

 

 

 

/*
Add IPTC PLUS Generative AI-ML Metadata to Open Doc scriptUI GUI.jsx
v1.0 - 26th September 2024, Stephen Marsh
v1.1 - 27th September 2024, Added a "None" option to remove data mining metadata
https://community.adobe.com/t5/photoshop-ecosystem-ideas/add-support-for-iptc-plus-coalition-generative-ai-ml-training-metadata/idi-p/14808232

https://iptc.org/news/exclude-images-from-generative-ai-iptc-photo-metadata-standard-2023-1/
https://ns.useplus.org/LDF/ldf-XMPSpecification#DataMining

Regional laws applying to an asset may prohibit, constrain, or allow data mining for certain purposes (such as search indexing or research), and may overrule the value selected for this property. Similarly, the absence of a prohibition does not indicate that the asset owner grants permission for data mining or any other use of an asset. The prohibition “Prohibited except for search engine indexing” only permits data mining by search engines available to the public to identify the URL for an asset and its associated data (for the purpose of assisting the public in navigating to the URL for the asset), and prohibits all other uses, such as AI/ML training.
*/

#target photoshop

if (app.documents.length) {
    // Create the ScriptUI dialog
    var dialog = new Window("dialog", "Add IPTC PLUS Data Mining Permission Metadata");
    dialog.orientation = "column";
    dialog.alignChildren = ["left", "top"];
    dialog.spacing = 10;
    dialog.margins = 16;

    // Create the label and dropdown menu
    dialog.add("statictext", undefined, "Data Mining Permission:");
    var dropdown = dialog.add("dropdownlist", undefined, [
        "Unspecified - no prohibition defined",
        "Allowed",
        "Prohibited for AI/ML training",
        "Prohibited for Generative AI/ML training",
        "Prohibited except for search engine indexing",
        "Prohibited",
        "None"  // Remove data mining metadata
    ]);
    dropdown.selection = 0;

    // Array of corresponding values
    var dropdownValues = [
        "DMI-UNSPECIFIED",
        "DMI-ALLOWED",
        "DMI-PROHIBITED-AIMLTRAINING",
        "DMI-PROHIBITED-GENAIMLTRAINING",
        "DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING",
        "DMI-PROHIBITED",
        ""  // "None"
    ];

    // Create OK and Cancel buttons
    var buttonGroup = dialog.add("group");
    buttonGroup.orientation = "row";
    buttonGroup.alignment = ["right", "top"];
    var okButton = buttonGroup.add("button", undefined, "OK");
    var cancelButton = buttonGroup.add("button", undefined, "Cancel");

    // Show the dialog
    if (dialog.show() == 1) {
        var contVocabEntry = dropdownValues[dropdown.selection.index];

        if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
        var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);

        if (contVocabEntry === "") {
            xmp.deleteProperty("http://ns.useplus.org/ldf/xmp/1.0/", "DataMining");
        } else {
            xmp.setProperty("http://ns.useplus.org/ldf/xmp/1.0/", "DataMining", "https://ns.useplus.org/ldf/vocab/" + contVocabEntry);
        }

        app.activeDocument.xmpMetadata.rawData = xmp.serialize();

        alert("Data Mining Permission set to: " + "\r" + dropdown.selection.text);
    }
} else {
    alert("A document must be open to run this script!");
}

 

 

Votes

Translate

Translate

Report

Report
LEGEND ,
Sep 26, 2024 Sep 26, 2024

Copy link to clipboard

Copied

Stephen, I modified your Bridge script to add a GUI and some error checking. *Final update*

 

 

/*
Add PLUS Generative AI-ML Metadata from Bridge Tools.jsx
v1.0 - 19th August 2024, Stephen Marsh
Modified 9-30-24 David M. Converse
https://community.adobe.com/t5/photoshop-ecosystem-ideas/add-support-for-iptc-plus-coalition-generative-ai-ml-training-metadata/idi-p/14808232

https://ns.useplus.org/LDF/ldf-XMPSpecification#DataMining

Example Controlled Vocabulary Entries:

https://ns.useplus.org/ldf/vocab/DMI-UNSPECIFIED
https://ns.useplus.org/ldf/vocab/DMI-ALLOWED
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-AIMLTRAINING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-GENAIMLTRAINING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED
*/
#target bridge
if(BridgeTalk.appName == 'bridge'){
    var MLmenu = MenuElement.create('command', 'Add PLUS GenAI-ML Metadata', 'at the end of Tools'); 
    }
try{
    MLmenu.onSelect = function(){
        if(ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); //load XMP Library
        var plusPrefix = 'https://ns.useplus.org/ldf/vocab/'; //shared prefix
        var ns = 'http://ns.useplus.org/ldf/xmp/1.0/';
        var contVocabEntry = ['DMI-UNSPECIFIED', 'DMI-ALLOWED', 'DMI-PROHIBITED-AIMLTRAINING', 'DMI-PROHIBITED-GENAIMLTRAINING', 'DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING', 'DMI-PROHIBITED']
        var ddlItem = contVocabEntry[0]; //initialize
        var sels = null;
        var md = null;
        var xmp = null;
        var updatedPacket = null;
        var j = 0;
        MLWindow = new Window('palette', '', undefined); //create window
        MLPanel = MLWindow.add('panel', undefined, 'PLUS Generative AL-ML Restrictions');
        MLPanel.alignChildren = ['fill', 'top'];
        MLPanel.margins = [10, 10, 10, 10];
        MLPanel.ddl = MLPanel.add('dropdownlist', undefined, '');
        MLPanel.ddl.preferredSize = [350, 25];
        for(var i = 0; i < 6; i++){ //add listitems
            ddlItem = contVocabEntry[i]; //walk through array of settings
            MLPanel.ddl.add('item', ddlItem);
            }
        MLPanel.ddl.add('item', 'None');
        MLPanel.ddl.selection = 0;
        MLGroup = MLWindow.add('group', undefined, '');
        MLGroup.orientation = 'row';
        MLGroup.alignChildren = ['fill', 'top'];
        MLGroup.cb = MLGroup.add('checkbox', undefined, 'Auto-close');
        MLGroup.cb.value = true;
        MLGroup.cb.preferredSize = [80, 25];
        MLGroup.spacer = MLGroup.add('statictext', undefined, '');
        MLGroup.spacer.size = [40, 25];
        MLGroup.button1 = MLGroup.add('button', undefined, 'Cancel');
        MLGroup.button1.preferredSize = [80, 25];
        MLGroup.button2 = MLGroup.add('button', undefined, 'Process');
        MLGroup.button2.preferredSize = [80, 25];

        MLGroup.button1.onClick = function(){ //cancel
            MLWindow.close();
            return;
            }
            
        MLGroup.button2.onClick = function(){ //process
            sels = app.document.selections;
            if(sels.length < 1){ //no selections
                Window.alert('Please select at least one file to process.'); 
                }
            else{
                for(j = 0; j < sels.length; j++){
                    try{
                        if(sels[j].hasMetadata && !sels[j].container){ //not a folder
                            md = sels[j].synchronousMetadata; //get metadata
                            xmp = new XMPMeta(md.serialize());
                            xmp.deleteProperty(ns, 'DataMining');
                            if(MLPanel.ddl.selection.index != 6){ //write value if not 'None'
                                xmp.setProperty(ns, 'DataMining', plusPrefix + contVocabEntry[MLPanel.ddl.selection.index]);
                                }
                            updatedPacket = xmp.serialize(XMPConst.SERIALIZE_OMIT_PACKET_WRAPPER | XMPConst.SERIALIZE_USE_COMPACT_FORMAT);
                            sels[j].metadata = new Metadata(updatedPacket); //write to file
                            }
                        }
                    catch(e){
                        Window.alert(e + e.line);
                        }
                    }
                if(MLGroup.cb.value == true){
                    MLWindow.close();
                    }
                }
            }

        MLWindow.layout.layout(true);
        MLWindow.show();
        MLWindow.active = true;
        }
    }
catch(e){
    Window.alert(e + ' ' + e.line);
    }

 

Votes

Translate

Translate

Report

Report
Community Expert ,
Sep 26, 2024 Sep 26, 2024

Copy link to clipboard

Copied

@Lumigraphics 

 

Thanks David, that’s fantastic! I like the "NONE" option to remove said metadata. I don't script Bridge very often and a GUI is extra hard work for me as well, so thank you for contributing.

Votes

Translate

Translate

Report

Report
LEGEND ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

@Stephen Marsh 

Yeah creating the GUI in every script is crazy, both Windows and Mac have built-in frameworks for building apps that don't require hand coding. I could completely remove the namespace instead of just making it blank but that takes a bit different approach and using XMPUTILS so I left it like this. I'm glad you posted this as I wasn't aware but I'm tagging all my images.

Votes

Translate

Translate

Report

Report
Community Expert ,
Sep 27, 2024 Sep 27, 2024

Copy link to clipboard

Copied

quote

I could completely remove the namespace instead of just making it blank but that takes a bit different approach and using XMPUTILS so I left it like this.


By @Lumigraphics 

 

I ironically used AI/ML to revise the Bridge script! :]

 

/*
Add IPTC PLUS Generative AI-ML Metadata from Bridge Tools scriptUI GUI.jsx
v1.0 - 19th August 2024, Stephen Marsh
Modified 26th September 2024 by David M. Converse - Added a scriptUI GUI and a "None" option
Modified 28th September 2024, by Stephen Marsh - Updated the code from David to completely remove the metadata without leaving any "debris" when "None" is selected
https://community.adobe.com/t5/photoshop-ecosystem-ideas/add-support-for-iptc-plus-coalition-generative-ai-ml-training-metadata/idi-p/14808232

https://iptc.org/news/exclude-images-from-generative-ai-iptc-photo-metadata-standard-2023-1/
https://ns.useplus.org/LDF/ldf-XMPSpecification#DataMining

Example Controlled Vocabulary Entries:

https://ns.useplus.org/ldf/vocab/DMI-UNSPECIFIED
https://ns.useplus.org/ldf/vocab/DMI-ALLOWED
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-AIMLTRAINING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-GENAIMLTRAINING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING
https://ns.useplus.org/ldf/vocab/DMI-PROHIBITED
*/

#target bridge

if (BridgeTalk.appName == 'bridge') {
    var MLmenu = MenuElement.create('command', 'Add IPTC PLUS GenAI-ML Metadata Window', 'at the end of Tools');
}
try {
    MLmenu.onSelect = function () {
        if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); //load XMP Library
        var plusPrefix = 'https://ns.useplus.org/ldf/vocab/'; //shared prefix
        var contVocabEntry = ['DMI-UNSPECIFIED', 'DMI-ALLOWED', 'DMI-PROHIBITED-AIMLTRAINING', 'DMI-PROHIBITED-GENAIMLTRAINING', 'DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING', 'DMI-PROHIBITED'];
        var ddlItem = contVocabEntry[0]; //initialize
        var sels = app.document.selections;
        var MLWindow = new Window('palette', '', undefined); //create window
        var MLPanel = MLWindow.add('panel', undefined, 'PLUS Generative AL-ML Restrictions');
        MLPanel.alignChildren = ['fill', 'top'];
        MLPanel.margins = [10, 10, 10, 10];
        MLPanel.ddl = MLPanel.add('dropdownlist', undefined, '');
        MLPanel.ddl.preferredSize = [350, 25];
        
        // Populate dropdown list
        for (var i = 0; i < contVocabEntry.length; i++) {
            MLPanel.ddl.add('item', contVocabEntry[i]);
        }
        MLPanel.ddl.add('item', 'NONE'); // Add 'None' option
        MLPanel.ddl.selection = 0;
        
        // Cancel and Process buttons
        var MLGroup = MLWindow.add('group', undefined, '');
        MLGroup.orientation = 'row';
        MLGroup.alignChildren = ['fill', 'top'];
        var cancelButton = MLGroup.add('button', undefined, 'Cancel');
        cancelButton.preferredSize = [80, 25];
        var processButton = MLGroup.add('button', undefined, 'Process');
        processButton.preferredSize = [80, 25];

        // Cancel button closes the window
        cancelButton.onClick = function () {
            MLWindow.close();
        };

        // Process button to update metadata
        processButton.onClick = function () {
            if (sels.length < 1) { // No selections
                MLWindow.close();
                return;
            }

            for (var j = 0; j < sels.length; j++) {
                if (sels[j].hasMetadata && !sels[j].container) { // Not a folder
                    var md = sels[j].synchronousMetadata;
                    var xmp = new XMPMeta(md.serialize()); // Create XMPMeta from file metadata

                    // Remove existing DataMining metadata
                    XMPUtils.removeProperties(xmp, 'http://ns.useplus.org/ldf/xmp/1.0/', 'DataMining', XMPConst.REMOVE_ALL_PROPERTIES);

                    // If dropdown selection is not 'None', add the new metadata
                    if (MLPanel.ddl.selection.index != 6) { // 'None' is at index 6
                        var selectedValue = plusPrefix + contVocabEntry[MLPanel.ddl.selection.index];
                        xmp.setProperty('http://ns.useplus.org/ldf/xmp/1.0/', 'DataMining', selectedValue);
                    }

                    // Write the updated metadata back to the file
                    var updatedPacket = xmp.serialize(XMPConst.SERIALIZE_OMIT_PACKET_WRAPPER); // Serialize without extra wrapper
                    sels[j].metadata = new Metadata(updatedPacket); // Assign the new metadata back to the file
                }
            }

            MLWindow.close(); // Close the window after processing
        };

        MLWindow.layout.layout(true);
        MLWindow.show();
        MLWindow.active = true;
    };
}
catch (e) {
    Window.alert(e + ' ' + e.line);
}

 

Minor updates to the Photoshop 1.2 version script:

 

/*
Add IPTC PLUS Generative AI-ML Metadata to Open Doc scriptUI GUI v1-2.jsx
v1.0 - 26th September 2024, Stephen Marsh
v1.1 - 27th September 2024, Added a "None" option to remove data mining metadata
v1.2 - 31st October 2024, Cosmetic Update to dropdown list text and default selection
https://community.adobe.com/t5/photoshop-ecosystem-ideas/add-support-for-iptc-plus-coalition-generative-ai-ml-training-metadata/idi-p/14808232

https://iptc.org/news/exclude-images-from-generative-ai-iptc-photo-metadata-standard-2023-1/
https://ns.useplus.org/LDF/ldf-XMPSpecification#DataMining

Regional laws applying to an asset may prohibit, constrain, or allow data mining for certain purposes (such as search indexing or research),and may overrule the value selected for this property. Similarly, the absence of a prohibition does not indicate that the asset owner grants permission for data mining or any other use of an asset. The prohibition “Prohibited except for search engine indexing” only permits data mining by search engines available to the public to identify the URL for an asset and its associated data (for the purpose of assisting the public in navigating to the URL for the asset), and prohibits all other uses, such as AI/ML training.
*/

#target photoshop

if (app.documents.length) {
    // Create the ScriptUI dialog
    var dialog = new Window("dialog", "Add IPTC PLUS Data Mining Permission Metadata (v1.2)");
    dialog.orientation = "column";
    dialog.alignChildren = ["left", "top"];
    dialog.preferredSize.width = 450;
    dialog.spacing = 10;
    dialog.margins = 16;

    // Create the label and dropdown menu
    dialog.add("statictext", undefined, "Data Mining Permission:");
    var dropdown = dialog.add("dropdownlist", undefined, [
        "Unspecified - no prohibition defined",
        "Allowed",
        "Prohibited for AI/ML training",
        "Prohibited for Generative AI/ML training",
        "Prohibited except for search engine indexing",
        "Prohibited",
        "None (Remove existing metadata)"  // Remove data mining metadata
    ]);
    dropdown.selection = 4; // Prohibited except for search engine indexing

    // Array of corresponding values
    var dropdownValues = [
        "DMI-UNSPECIFIED",
        "DMI-ALLOWED",
        "DMI-PROHIBITED-AIMLTRAINING",
        "DMI-PROHIBITED-GENAIMLTRAINING",
        "DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING",
        "DMI-PROHIBITED",
        ""  // "None"
    ];

    // Create OK and Cancel buttons
    var buttonGroup = dialog.add("group");
    buttonGroup.orientation = "row";
    buttonGroup.alignment = ["right", "top"];
    var cancelButton = buttonGroup.add("button", undefined, "Cancel");
    var okButton = buttonGroup.add("button", undefined, "OK");

    // Show the dialog
    if (dialog.show() == 1) {
        var contVocabEntry = dropdownValues[dropdown.selection.index];

        if (ExternalObject.AdobeXMPScript === undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
        var xmp = new XMPMeta(activeDocument.xmpMetadata.rawData);

        if (contVocabEntry === "") {
            xmp.deleteProperty("http://ns.useplus.org/ldf/xmp/1.0/", "DataMining");
        } else {
            xmp.setProperty("http://ns.useplus.org/ldf/xmp/1.0/", "DataMining", "https://ns.useplus.org/ldf/vocab/" + contVocabEntry);
        }

        app.activeDocument.xmpMetadata.rawData = xmp.serialize();

        alert("Data Mining Permission set to: " + "\r" + dropdown.selection.text);
    }
} else {
    alert("A document must be open to run this script!");
}

 

 

Votes

Translate

Translate

Report

Report
LEGEND ,
Sep 28, 2024 Sep 28, 2024

Copy link to clipboard

Copied

Yes that's how. I usually serialize the XMP because there are more tools to work with it. I was just being lazy 😉

Votes

Translate

Translate

Report

Report
LEGEND ,
Sep 30, 2024 Sep 30, 2024

Copy link to clipboard

Copied

And final update posted, switching method of editing xmp and allowing the GUI to remain open or auto-close.

Votes

Translate

Translate

Report

Report
Community Expert ,
Oct 31, 2024 Oct 31, 2024

Copy link to clipboard

Copied

I have updated the Photoshop script to a v2.0, now including batch processing:

 

Add IPTC PLUS Generative AI-ML Metadata scriptUI GUI v2.png

 

* The interface defaults to "Single Document" mode on an open/active document.

 

* The interface defaults to "Batch Processing" mode if the script is run without any open documents. Select a root/top-level folder and optionally all sub-folders.

 

/*
Add IPTC PLUS Generative AI-ML Metadata scriptUI GUI v2.jsx
v1.0 - 26th September 2024, Stephen Marsh
v1.1 - 27th September 2024, Added a "None" option to remove data mining metadata
https://community.adobe.com/t5/photoshop-ecosystem-ideas/add-support-for-iptc-plus-coalition-generative-ai-ml-training-metadata/idi-p/14808232

https://iptc.org/news/exclude-images-from-generative-ai-iptc-photo-metadata-standard-2023-1/
https://ns.useplus.org/LDF/ldf-XMPSpecification#DataMining

Regional laws applying to an asset may prohibit, constrain, or allow data mining for certain purposes (such as search indexing or research), and may overrule the value selected for this property. Similarly, the absence of a prohibition does not indicate that the asset owner grants permission for data mining or any other use of an asset. The prohibition “Prohibited except for search engine indexing” only permits data mining by search engines available to the public to identify the URL for an asset and its associated data (for the purpose of assisting the public in navigating to the URL for the asset), and prohibits all other uses, such as AI/ML training.
*/

#target photoshop

// Create the ScriptUI dialog
var dialog = new Window("dialog", "Add IPTC PLUS Data Mining Permission Metadata (v2.0)");
dialog.orientation = "column";
dialog.alignChildren = ["fill", "top"];
dialog.preferredSize.width = 450;
dialog.spacing = 10;
dialog.margins = 16;

// Create panel for single document processing
var singlePanel = dialog.add("panel", undefined, "Single Document Processing Options");
singlePanel.orientation = "column";
singlePanel.alignChildren = ["fill", "top"];
singlePanel.margins = 16;

// Add "Data Mining Permission" label and dropdown to singlePanel
singlePanel.add("statictext", undefined, "Data Mining Permission:");
var singleDropdown = singlePanel.add("dropdownlist", undefined, [
    "Unspecified - no prohibition defined",
    "Allowed",
    "Prohibited for AI/ML training",
    "Prohibited for Generative AI/ML training",
    "Prohibited except for search engine indexing",
    "Prohibited",
    "None (Remove existing metadata)"
]);
singleDropdown.selection = 4; // Default selection

// Array of corresponding values for metadata entries
var dropdownValues = [
    "DMI-UNSPECIFIED",
    "DMI-ALLOWED",
    "DMI-PROHIBITED-AIMLTRAINING",
    "DMI-PROHIBITED-GENAIMLTRAINING",
    "DMI-PROHIBITED-EXCEPTSEARCHENGINEINDEXING",
    "DMI-PROHIBITED",
    ""
];

// Create panel for batch processing
var batchPanel = dialog.add("panel", undefined, "Batch Processing Options");
batchPanel.orientation = "column";
batchPanel.alignChildren = ["fill", "top"];
batchPanel.margins = 16;

// Add "Data Mining Permission" label and dropdown to batchPanel
batchPanel.add("statictext", undefined, "Data Mining Permission:");
var batchDropdown = batchPanel.add("dropdownlist", undefined, [
    "Unspecified - no prohibition defined",
    "Allowed",
    "Prohibited for AI/ML training",
    "Prohibited for Generative AI/ML training",
    "Prohibited except for search engine indexing",
    "Prohibited",
    "None (Remove existing metadata)"
]);
batchDropdown.selection = 4; // Default selection

// Folder selection for batch processing
batchPanel.add("statictext", undefined, "Select Folder:");
var browseGroup = batchPanel.add("group");
browseGroup.orientation = "row";
browseGroup.alignChildren = ["left", "center"];
browseGroup.spacing = 5;

var selectFolderButton = browseGroup.add("button", undefined, "Select Folder");
selectFolderButton.preferredSize.width = 80;

var folderPath = browseGroup.add("edittext");
folderPath.text = "No folder selected";
folderPath.enabled = false; // Read-only
folderPath.alignment = ["fill", "center"]; // Fill width

// Checkbox to include subfolders
var subFolderCheckbox = batchPanel.add("checkbox", undefined, "Include Subfolders");

// Set panel states based on open documents
if (app.documents.length === 0) {
    batchPanel.enabled = true;
    singlePanel.enabled = false;
} else {
    batchPanel.enabled = false;
    singlePanel.enabled = true;
}

// Select folder button functionality
selectFolderButton.onClick = function () {
    var selectedFolder = Folder.selectDialog("Select the root folder for batch processing");
    if (selectedFolder) folderPath.text = selectedFolder.fsName;
};

// Create Cancel and OK buttons
var buttonGroup = dialog.add("group");
buttonGroup.orientation = "row";
buttonGroup.alignment = ["right", "top"];
var cancelButton = buttonGroup.add("button", undefined, "Cancel");
var okButton = buttonGroup.add("button", undefined, "OK");

// Show the dialog
if (dialog.show() == 1) {
    var contVocabEntry = (batchPanel.enabled ? dropdownValues[batchDropdown.selection.index] : dropdownValues[singleDropdown.selection.index]);

    // Check if the AdobeXMPScript library is available
    if (ExternalObject.AdobeXMPScript === undefined) {
        try {
            ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
        } catch (e) {
            alert("Unable to load AdobeXMPScript. Please ensure the library is available.");
            dialog.close();
        }
    }

    // Function to update XMP metadata for a given file without opening it
    function updateXMP(filePath) {
        var xmpFile = new XMPFile(filePath.fsName, XMPConst.FILE_JPEG, XMPConst.OPEN_FOR_UPDATE);
        var xmp = xmpFile.getXMP();

        if (contVocabEntry === "") {
            xmp.deleteProperty("http://ns.useplus.org/ldf/xmp/1.0/", "DataMining");
        } else {
            xmp.setProperty("http://ns.useplus.org/ldf/xmp/1.0/", "DataMining", "https://ns.useplus.org/ldf/vocab/" + contVocabEntry);
        }

        if (xmpFile.canPutXMP(xmp)) {
            xmpFile.putXMP(xmp);
        }
        xmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
    }

    // Process the active document if batch processing is disabled
    if (!batchPanel.enabled) {
        var xmp = new XMPMeta(app.activeDocument.xmpMetadata.rawData);

        if (contVocabEntry === "") {
            xmp.deleteProperty("http://ns.useplus.org/ldf/xmp/1.0/", "DataMining");
        } else {
            xmp.setProperty("http://ns.useplus.org/ldf/xmp/1.0/", "DataMining", "https://ns.useplus.org/ldf/vocab/" + contVocabEntry);
        }

        app.activeDocument.xmpMetadata.rawData = xmp.serialize();
        alert("Data Mining Permission set to: " + "\r" + singleDropdown.selection.text);
    }
    // Process files in the selected folder and subfolders if batch processing is enabled
    else {
        if (folderPath.text === "" || folderPath.text === "No folder selected") {
            alert("Please select a folder for batch processing.");
        } else {
            var rootFolder = new Folder(folderPath.text);

            // Recursive function to process files in folder and subfolders if selected
            function processFolder(folder) {
                var files = folder.getFiles();
                for (var i = 0; i < files.length; i++) {
                    var file = files[i];
                    if (file instanceof Folder && subFolderCheckbox.value) {
                        processFolder(file); // Recurse into subfolders
                    } else if (file instanceof File && file.name.match(/\.(png|webp|jpg|jpeg|tif|tiff|psd|psb)$/i)) {
                        updateXMP(file); // Update metadata for valid image files
                    }
                }
            }

            processFolder(rootFolder);
            alert("Batch processing complete. Data Mining Permission set to: " + "\r" + batchDropdown.selection.text);
        }
    }
} else {
    dialog.close();
}

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html 

Votes

Translate

Translate

Report

Report
Explorer ,
Oct 31, 2024 Oct 31, 2024

Copy link to clipboard

Copied

Thank you! These scripts look very useful.

Votes

Translate

Translate

Report

Report
Community Expert ,
Nov 01, 2024 Nov 01, 2024

Copy link to clipboard

Copied

LATEST

@Ultimatebeetle 

 

I think the jury is out on that... It's an opt-in and honour system, and I don't believe that any of the AI players are following such flags, but it can't hurt.  :]

Votes

Translate

Translate

Report

Report