Skip to main content
Participant
June 6, 2019
Answered

Bridge script to write filename to Description, Credit Line, andTitle lines

  • June 6, 2019
  • 5 replies
  • 10709 views

Hello! I'm in search of a Bridge script that will write a filename (without file extension) to the description line, title line, and Credit line (without overwriting!) in my IPTC metadata. I've looked around and haven't found something already written that does this and I don't quite have enough skills to write it myself or adapt something that exists already. Any leads or suggestions? Thanks!!

This topic has been closed for replies.
Correct answer Stephen Marsh

Using ExifTool, the command line code to copy the filename to the description metadata tag without extension would be:

 

 

exiftool '-description<${filename;s/\.[^\.]+$//}' -r 'path to file or folder here'

 

 

This command line code example is from the Mac, on Windows simply change the single straight quote/foot mark ' to straight double quote/inch marks " with the correct platform-specific path to the file or top-level folder. It uses a recursive argument to process all files in all folders under the top-level folder. Further arguments can be added to only process certain file types or to ignore specific directories under the top-level directory path. This code duplicates and renames the original file for safety, and one can add the -overwrite_original argument to turn off this behaviour.

 

5 replies

Stephen Marsh
Community Expert
Community Expert
November 16, 2023

An addition raised in another topic in the Photoshop forum... The following script can be used to find/replace/remove title data (I believe that this script was most likely written by Paul Riggot):

 

To clear the title you can use a regular expression find (replacing with nothing):

 

.+

 

 

#target bridge
if (BridgeTalk.appName == "bridge") {
    ReplaceTitle = new MenuElement("command", "Find and Replace in Title", "at the end of tools");
}
ReplaceTitle.onSelect = function () {
    var win = new Window('dialog', 'Find & Replace in Title');
    g = win.graphics;
    var myBrush = g.newBrush(g.BrushType.THEME_COLOR, "appDialogBackground");
    g.backgroundColor = myBrush;
    win.orientation = 'column';
    win.p1 = win.add("panel", undefined, undefined, { borderStyle: "black" });
    win.p1.preferredSize = [380, 100];
    win.g1 = win.p1.add('group');
    win.g1.orientation = "row";
    win.title = win.g1.add('statictext', undefined, 'Title Editor');
    win.title.alignment = "fill";
    var g = win.title.graphics;
    g.font = ScriptUI.newFont("Arial", "BOLD", 22);
    win.p6 = win.p1.add("panel", undefined, undefined, { borderStyle: "black" }); //Replace
    win.p6.preferredSize = [380, 100];
    win.g600 = win.p6.add('group');
    win.g600.orientation = "row";
    win.g600.alignment = 'fill';
    win.g600.st1 = win.g600.add('statictext', undefined, 'Replace');
    win.g600.st1.preferredSize = [75, 20];
    win.g600.et1 = win.g600.add('edittext');
    win.g600.et1.preferredSize = [200, 20];
    win.g610 = win.p6.add('group');
    win.g610.orientation = "row";
    win.g610.alignment = 'fill';
    win.g610.st1 = win.g610.add('statictext', undefined, 'With');
    win.g610.st1.helpTip = "Leave this field blank if you want to remove the characters";
    win.g610.st1.preferredSize = [75, 20];
    win.g610.et1 = win.g610.add('edittext');
    win.g610.et1.preferredSize = [200, 20];
    win.g620 = win.p6.add('group');
    win.g620.orientation = "row";
    win.g620.alignment = 'fill';
    win.g620.cb1 = win.g620.add('checkbox', undefined, 'Global');
    win.g620.cb1.helpTip = "Replace all occurrences of";
    win.g620.cb2 = win.g620.add('checkbox', undefined, 'Case Insensitive');
    win.g620.cb2.value = true;
    win.g1000 = win.p1.add('group');
    win.g1000.orientation = "row";
    win.g1000.alignment = 'center';
    win.g1000.bu1 = win.g1000.add('button', undefined, 'Process');
    win.g1000.bu1.preferredSize = [170, 30];
    win.g1000.bu2 = win.g1000.add('button', undefined, 'Cancel');
    win.g1000.bu2.preferredSize = [170, 30];
    win.g1000.bu1.onClick = function () {
        if (win.g600.et1.text == '') {
            alert("No replace value has been entered!");
            return;
        }
        win.close(0);
        var sels = app.document.selections;
        for (var a in sels) {
            var thumb = sels[a];
            md = thumb.synchronousMetadata;
            if (win.g620.cb1.value && !win.g620.cb2.value) var patt = new RegExp(win.g600.et1.text.toString(), "g");
            if (!win.g620.cb1.value && win.g620.cb2.value) var patt = new RegExp(win.g600.et1.text.toString(), "i");
            if (win.g620.cb1.value && win.g620.cb2.value) var patt = new RegExp(win.g600.et1.text.toString(), "gi");
            if (!win.g620.cb1.value && !win.g620.cb2.value) var patt = new RegExp(win.g600.et1.text.toString());
            md.namespace = "http://purl.org/dc/elements/1.1/";
            var Caption = md.title ? md.title[0] : "";
            if (Caption == "") continue;
            var result = patt.test(Caption.toString());
            if (result == true) {
                var newCaption = Caption.replace(patt, win.g610.et1.text.toString());
                setTitle(sels[a].spec, newCaption);
            }
        }
    }
    win.show();
    function setTitle(file, Caption) {
        if (!ExternalObject.AdobeXMPScript) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
        var xmpf = new XMPFile(File(file).fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE);
        var xmp = xmpf.getXMP();
        xmp.deleteProperty(XMPConst.NS_DC, "title");
        xmp.setLocalizedText(XMPConst.NS_DC, "title", null, "x-default", Caption);
        if (xmpf.canPutXMP(xmp)) {
            xmpf.putXMP(xmp);
        }
        xmpf.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
    }
};

 

 

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

_wckdTall_
Inspiring
November 29, 2023

Thanks again for this. I think the issue is that the persistent data occurs outside of metadata. I did get it to replace the title, but it doesn't replace the additional title fields in the file. Is there a way to access these via bridge? I've been poking around with John Wundes "The Document Object Model Explorer v.2 -- CS", but it stops reading the objects quickly. It wasn't intended for this, but does a pretty good job with InDesign and Photoshop. 

_wckdTall_
Inspiring
November 29, 2023

Still interested if there's a way to adjust info outside of headers within bridge. But in testing, I've found that the reason AEM was recognizing these extraneous titles, was because I was deleting XMP title field but not appending a blank one back and setting a qualifier.

        myXmp.deleteProperty(XMPConst.NS_DC, "title");
        myXmp.appendArrayItem(XMPConst.NS_DC, "title", Title, 0, XMPConst.ALIAS_TO_ALT_TEXT);
myXmp.setQualifier(XMPConst.NS_DC, "title[1]", "http://www.w3.org/XML/1998/namespace", "lang", "x-default");


Titles still incorrectly appear here(I think this is postscript/pdf?):

%!PS-Adobe-3.0 
%%Creator: Adobe Illustrator(R) 24.0
%%AI8_CreatorVersion: 28.0.0
%%For: (MY_USER_NAME) ()
%%Title: (Untitled-3)

And here, this is where AEM pulls from if it doesn't have a title field:

35 0 obj
<</CreationDate(D:20231128231255-05'00')/Creator(Adobe Illustrator 28.0 \(Macintosh\))/ModDate(D:20231128231256-05'00')/Producer(Adobe PDF library 17.00)/Title(THIS_IS_ANOTHER_TITLE)>>
endobj
xref


I have opened the AI files within text edit to find these additional titles, would love to know how to remove extraneous data like this, since at it contains user names etc. Not sure if it's related, but I saw exif tool does have a "For" field that read in the username.

Stephen Marsh
Community Expert
Community Expert
April 5, 2021

 

MarkLane1 

 

It turns out that I didn't have a script that writes the filename to both the Description and Title metadata fields.

 

I have adjusted an existing script for Description to also include the Title:

 

/* Original script modified by Stephen Marsh - 2021
https://community.adobe.com/t5/bridge/bridge-script-to-write-filename-to-description-credit-line-andtitle-lines/td-p/10489128
https://forums.adobe.com/thread/2009311 */

#target bridge

if (BridgeTalk.appName == "bridge") {
    FT = MenuElement.create("command", "Add Filename to Description and Title", "at the end of Tools");
}

FT.onSelect = function () {
    var thumbs = app.document.selections;
    if (!thumbs.length) return;
    if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");

    for (var a in thumbs) {
        var selectedFile = thumbs[a].spec;
        var FileName = decodeURI(selectedFile.name).replace(/\.[^\.]+$/, '');
        var myXmpFile = new XMPFile(selectedFile.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE);
        var myXmp = myXmpFile.getXMP();
        var Desc = [];
        var Title = [];
        var descCount = myXmp.countArrayItems(XMPConst.NS_DC, "description");
        var titleCount = myXmp.countArrayItems(XMPConst.NS_DC, "title");

        for (var i = 1; i <= descCount; i++) {
            Desc.push(myXmp.getArrayItem(XMPConst.NS_DC, "description", i));
        }

        for (var i = 1; i <= titleCount; i++) {
            Title.push(myXmp.getArrayItem(XMPConst.NS_DC, "title", i));
        }

        Desc = Desc.toString() + " " + FileName;
        Title = Desc;

        myXmp.deleteProperty(XMPConst.NS_DC, "description");
        myXmp.appendArrayItem(XMPConst.NS_DC, "description", Desc, 0, XMPConst.ALIAS_TO_ALT_TEXT);
        myXmp.setQualifier(XMPConst.NS_DC, "description[1]", "http://www.w3.org/XML/1998/namespace", "lang", "x-default");

        myXmp.deleteProperty(XMPConst.NS_DC, "title");
        myXmp.appendArrayItem(XMPConst.NS_DC, "title", Title, 0, XMPConst.ALIAS_TO_ALT_TEXT);
        myXmp.setQualifier(XMPConst.NS_DC, "title[1]", "http://www.w3.org/XML/1998/namespace", "lang", "x-default");

        if (myXmpFile.canPutXMP(myXmp)) {
            myXmpFile.putXMP(myXmp);
            myXmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
        }
    }
}

 

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

 

 

Participating Frequently
April 5, 2021

I was searching for a way to do just this, and found the original Script by John Beardsworth works with changes to the meta line needed. But I was wondering, is there a way to have only part of the file name placed into each line, on mass?
eg. I have a filename structure of:  

ABCD 0123 ABCD AB-CD AB19 0123 AB19 AB19.jpg

so sections:

A B C D E F G H.jpg

Basicly a whole mix of alphanumerics some fixed length some not. All delimiters are spaces (but can be anything).

I was wondering if it was possible to write section A to, say, Comments. B to City, C to Source, D to Headline, etc....

So far I've been doing it long hand by renaming the files to only the relevant section Setting the metadata with johns script and reverting the filename, repeating for each section. I am using a dusted off copy of cs6 as i cant get these to run in CC.
I know there is a way to do this in ExifTool but I'm still learning the syntax and cant figure out the right commands, plus if im not around at least someone else can just hit a button in Bridge with out me explaining how to work Exiftool to them.

Any help would be greatly appreciated.

Stephen Marsh
Community Expert
Community Expert
April 5, 2021

Its the seperate fields I am hoping to achieve. eg:

the Blue section fills the Description field.

Red into Headline

Green into Source

Pink into City

Etc...

so each line of meta data contains one part of the whole filename as each is relevant in differnt ways.


There may be a better way, which is why I am trying to understand what you are doing or hoping to achive.

Participating Frequently
June 11, 2020

Did you ever find a Bridge script to write filename to Description? I too am interested in finding a script like this for the newest version of Adobe Bridge. Can you share any resources?

Morgan Howarth

[Edit by moderator: I've taken out your public email, you probably do not want to share that with everyone]

 

Please PM me if you have information! Thank you.

Participating Frequently
June 12, 2020

I personally have not found a way to do it, I got ACDSee Professional thinking that would do it for me, but the system is so trashy, having to manually select each and every folder in a pull down menu and no way to select all sub-folders in a parent folder, it's an antiquated system at best, when I added one parent folder with all my location shots the program ceased to work properly, it now takes 10 minutes just to load up so I need to remove all the catalog files and start again 😞 
ACDsee does write the tags perfectly if you are willing to manually set each folder, but for me (I have over 100,000 photographs I'd like to change the EXIF on) this is no good.

It seems all we want is a simple program to read an XML file and write the relevant tags, hard to believe such a thing does not exist.

Participating Frequently
May 17, 2020

It's hard to believe that in 2020 this feature is not a standard in Adobe - All photographers use META and for me the best program for writing it is ACDSee as this feature has existed for a decade, but I am looking at swapping to Adobe products but all these limitations with XMP over XML are putting me off switching over. It would be nice if we had a way of just selecting a Parent folder, then everything inside those folders get written too, this is possible in ACDSee but you have toi tag each folder which makes it a long winded process but wtill much better than this Bridge nonsense 😕😕

Stephen Marsh
Community Expert
Community Expert
June 7, 2019

I don't have one script that does all three... But I do have three separate scripts. I could possibly combine them with time/effort, but no promises as I'm new to scripting.

I did manage to hack an existing script to add the Filename to the Headline into the Credit:

// Bridge script to write filename to Description, Credit Line, andTitle lines

// https://forums.adobe.com/thread/656144 

// https://forums.adobe.com/message/9744916 

// https://forums.adobe.com/message/9745231 

#target bridge 

addNametoMeta = {}; 

addNametoMeta.execute = function(){ 

  var sels = app.document.selections; 

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

var md = sels.synchronousMetadata; 

    md.namespace = "http://ns.adobe.com/photoshop/1.0/"; 

    var Name = decodeURI(sels.name).replace(/\.[^\.]+$/g, ' '); //remove extension  

    md.Credit = md.Credit + Name; 

  } 

if (BridgeTalk.appName == "bridge"){ 

var menu = MenuElement.create( "command", "Add filename to Credit", "at the end of Tools"); 

  menu.onSelect = addNametoMeta.execute; 

}

Here is the code for Filename to Description:

// https://forums.adobe.com/message/10061534#10061534

// https://forums.adobe.com/message/3595421#3595421

#target bridge

   if( BridgeTalk.appName == "bridge" ) {

fileToDesc = MenuElement.create("command", "Add FileName to Description", "at the end of Tools");

}

fileToDesc.onSelect  = function () {

var thumbs = app.document.selections;

if (ExternalObject.AdobeXMPScript == undefined)  ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");

for(var a =0;a<thumbs.length;a++){

var selectedFile =  new Thumbnail(thumbs);

app.synchronousMode = true;

var xmp = new XMPMeta(selectedFile.synchronousMetadata.serialize());

var Desc = getArrayItems(XMPConst.NS_DC, "description");

if(Desc != "") Desc+= ";";

xmp.deleteProperty(XMPConst.NS_DC, "description");

xmp.setLocalizedText( XMPConst.NS_DC, "description", null, "x-default", Desc +=  decodeURI(selectedFile.spec.name).replace(/\..+$/,""));

var newPacket = xmp.serialize(XMPConst.SERIALIZE_USE_COMPACT_FORMAT);

selectedFile.metadata = new Metadata(newPacket);

    }

ExternalObject.AdobeXMPScript.unload();

ExternalObject.AdobeXMPScript = undefined;

function getArrayItems(ns, prop){

var arrItem=[];

try{

var items = xmp.countArrayItems(ns, prop);

for(var i = 1;i <= items;i++){

arrItem.push(xmp.getArrayItem(ns, prop, i));

}

return arrItem.toString();

}catch(e){alert(e +" Line: "+ e.line);}

    }

};

Here is the code for Filename to Title:

// https://imagesimple.wordpress.com/2011/08/24/cs5-filename-to-title-script/

#target bridge

   if( BridgeTalk.appName == "bridge" ) {

FT = MenuElement.create("command", "Add FileName to Title", "at the end of Tools");

}

FT.onSelect = function () {

   AddFilenameToTitle();

   }

function AddFilenameToTitle(){

var thumbs = app.document.selections;

if(!thumbs.length) return;

if (ExternalObject.AdobeXMPScript == undefined)  ExternalObject.AdobeXMPScript = new

ExternalObject("lib:AdobeXMPScript");

for(var a in thumbs){

var selectedFile = thumbs.spec;

var Title = decodeURI(selectedFile.name).replace(/\.[^\.]+$/, '')

      var myXmpFile = new XMPFile( selectedFile.fsName, XMPConst.UNKNOWN,

XMPConst.OPEN_FOR_UPDATE);

  var myXmp = myXmpFile.getXMP();

        myXmp.deleteProperty(XMPConst.NS_DC, "title");

        myXmp.appendArrayItem(XMPConst.NS_DC, "title", Title, 0,

XMPConst.ALIAS_TO_ALT_TEXT);

        myXmp.setQualifier(XMPConst.NS_DC, "title[1]",

"http://www.w3.org/XML/1998/namespace", "lang", "x-default");

        if (myXmpFile.canPutXMP(myXmp)) {

        myXmpFile.putXMP(myXmp);

         myXmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);

         }

    }

}

After running all three scripts, I used ExifTool to confirm which metadata tags were written:

[IPTC]           ObjectName                    

[IPTC]           Credit                         

[IPTC]           Caption-Abstract               

[IFD0]           ImageDescription               

[XMP-dc]     Title                          

[XMP-dc]     Description                    

[XMP-photoshop]    Credit

And here is the result from Bridge's Metadata panel for a file titled "colour FILE-Test.psd":

Stephen Marsh
Community Expert
Community Expert
June 7, 2019

An equivalent ExifTool command line could be:

exiftool '-IPTC:ObjectName<${filename;s/\.[^.]*$//}' '-IPTC:Credit<${filename;s/\.[^.]*$//}' '-IPTC:Caption-Abstract<${filename;s/\.[^.]*$//}' '-IFD0:ImageDescription<${filename;s/\.[^.]*$//}' '-XMP-dc:Title<${filename;s/\.[^.]*$//}' '-XMP-dc:Description<${filename;s/\.[^.]*$//}' '-XMP-photoshop:Credit<${filename;s/\.[^.]*$//}' -r 'pathTOfileORfolder'