Working with metadata in CS2

Photoshop Script Snippets - Note: Full Scripts go in the Photoshop Scripts Forum

Moderators: Tom, Kukurykus

Mike Hale

Working with metadata in CS2

Post by Mike Hale »

I have been working to a project that creates new metadata in a custom namespace. I have a script that extracts data from a tif file and creates a template to add the metadata. But I hit a roadblock when it came to having the script append the template. Javascript doesn't have an object to work with templates and scriptlistner only records the opening of the FileInfo dialog where it can be done in the GUI. I was also unable to find anything searching the forums/web. So here is what I have come up with to let you append a template.

By using bridge talk you can have Bridge to the work for you. First you need to point bridge to the folder your file you want to update is in. This function will open bridge if it's not open and point it to a folder whether it was open or not.

Code: Select allfunction openBridge(folder){// folder as String "~/Desktop/"
   var bt = new BridgeTalk ();
   var theScript = 'app.browseTo("'+folder+'");';
   bt.target = 'bridge';
   bt.body = theScript;
   bt.send();   
};

Now that bridge is ready, here is the function to append the template. The template needs to be in the template folder.

Code: Select allfunction appendMeta(filePath,xmpTemplate) {// As Strings ie appendMeta("~/Desktop/bob.tif","bob")
   var bt = new BridgeTalk ();
   var theScript = 'tn = new Thumbnail( File("'+filePath+'") );app.document.deselectAll();app.document.select(tn);md = tn.synchronousMetadata;md.applyMetadataTemplate("'+xmpTemplate+'", "append");';
   bt.target = 'bridge';
   bt.body = theScript;
   bt.send();   
};

If you only have one or two items you want to add to the metadata you can skip the template and add them directly. Note that you will need to know the namespace that holds the data and some data types can't be written. Some are read-only as well. Also watch out for typos in your code, if there is a typo in the namespace or dataProperty string Bridge will create a new namespace or property.

Code: Select allfunction setMetadata(filePath,namespace,dataProperty,dataValue) {// As Strings ie setMetadata("~/Desktop/sem_tmp_file.tif","http://ns.sem.com/semsa/1.0/","User")
   var bt = new BridgeTalk ();
   var theScript = 'tn = new Thumbnail( File("'+filePath+'") );md = tn.synchronousMetadata;md.namespace = "'+namespace+'";md.'+dataProperty+' = "'+dataValue+'";md.'+dataProperty+';';
   bt.target = 'bridge';
   bt.body = theScript;
   bt.send();   
};

Bridge talk is able to send back information but I have been unable to get that to work for me. So the above functions don't return a success or error.

Which leads me to the next function. This one gets the value of a metadata property. But because I can't get the onResult method to work for me, that value stays in bridge and doesn't return to photoshop. Here is the function without the onResult callback

Code: Select allfunction getMetadata(filePath,namespace,dataProperty) {// As Strings ie getMetadata("~/Desktop/sem_tmp_file.tif","http://ns.sem.com/semsa/1.0/","User")
   var bt = new BridgeTalk ();
   var theScript = 'tn = new Thumbnail( File("'+filePath+'") );md = tn.synchronousMetadata;md.namespace = "'+namespace+'";var a = md.'+dataProperty+';md.toSource();'
   bt.target = 'bridge';
   bt.body = theScript;
   bt.send();
};
 
var test = getMetadata("~/Desktop/sem_tmp_file.tif","http://ns.sem.com/semsa/1.0/","User")

If anyone know how to get the callback to work, please let me know

Mike
Mike Hale

Working with metadata in CS2

Post by Mike Hale »

Xbytor explained how to get data back from bridge talk http://ps-scripts.com/bb/viewtopic.php?t=795 and posted a helper function.

Here is the getMetadata function working thanks to him

Code: Select all// Send a synchronous message. The result is returned.
// If a result doesn't come back in 'timeout' seconds, undefined is returned.
BridgeTalk.prototype.sendSynch = function(timeout) {
  var self = this;
  self.onResult = function(res) {
    this.result = res.body;
    this.complete = true;
  }
  self.complete = false;

  self.send();

  if (timeout) {
    for (var i = 0; i < timeout; i++) {
      BridgeTalk.pump();       // process any outstanding messages
      if (!self.complete) {
        $.sleep(1000);
      } else {
        break;
      }
    }
  }

  var res = self.result;
  self.result = self.complete = self.onResult = undefined;
  return res;
};
// for typos, provide an alias
BridgeTalk.prototype.sendSync = BridgeTalk.prototype.sendSynch;

function test(filePath,namespace,dataProperty) {
  var bridgeApp = "bridge-1.0";

  if (!BridgeTalk.isRunning(bridgeApp)) {
    BridgeTalk.launch(bridgeApp);
  }

  var bt = new BridgeTalk();
  bt.target = bridgeApp;
  bt.body = 'tn = new Thumbnail( File("'+filePath+'") );md = tn.synchronousMetadata;md.namespace = "'+namespace+'";var a = md.'+dataProperty+';a;'
  var res = bt.sendSynch(10);
  alert(res);
};

test("~/Desktop/a.jpg","http://ns.sem.com/sema/1.0/","stagey")

To make this really useful I'm going to try using Bob Stucky's mdns object to return all the metadata at once.