Skip to main content
JBL
Known Participant
April 29, 2010
Question

How can you use Javascript to enter metadata into a PSD, and pull it out later?

  • April 29, 2010
  • 1 reply
  • 3354 views

Developing an app for a non-profit, and I'm half way there, but stuck at:

#1. Getting a file location reference when the .jpg is first brought into PS as a layer.

#2. Getting a script to write into the medata for the PSD in some field

#3. Getting a script to read back the metadata from the PSD to use in other scripts.

#1 will be the toughest, but does anyone know how to do #2 and #3?

This topic has been closed for replies.

1 reply

Inspiring
April 30, 2010

This will place a file as a smart object then write the file's path to the exif:userComment of the layer's metadata. The it reads the layer's comment and alerts the file's path.

// these function adapted from PerLayerMetdata.jsx -Copyright 2008 Adobe Systems Incorporated
function loadXMPLibrary(){
     if ( !ExternalObject.AdobeXMPScript ){
          try{
               ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
          }catch (e){
               alert("Can't load XMP Script Library");
               return false;
          }
     }
     return true;
};
function setCommMetadata(comm){
     if( app.activeDocument.activeLayer.isBackgroundLayer){
          alert( 'Can not place metadata on a background layer.' );
     } else {
          var xmp;
          if ( comm == "" )
               comm = " ";
               
          try{
               xmp = new XMPMeta( app.activeDocument.activeLayer.xmpMetadata.rawData );
          } catch( e ) {
               xmp = new XMPMeta();
          }
          try{
               xmp.setProperty( XMPConst.NS_EXIF, "userComment", comm );
          } catch( e ) {
               alert( 'Unable to place metadata on selected layer.\n' + e );
          }
          app.activeDocument.activeLayer.xmpMetadata.rawData = xmp.serialize();
     }
};
function placeFile( file) {
    var desc = new ActionDescriptor();
    desc.putPath( charIDToTypeID('null'), file );
    desc.putEnumerated( charIDToTypeID('FTcs'), charIDToTypeID('QCSt'), charIDToTypeID('Qcsa') );
        var offsetDesc = new ActionDescriptor();
        offsetDesc.putUnitDouble( charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), 0.000000 );
        offsetDesc.putUnitDouble( charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), 0.000000 );
    desc.putObject( charIDToTypeID('Ofst'), charIDToTypeID('Ofst'), offsetDesc );
    executeAction( charIDToTypeID('Plc '), desc, DialogModes.NO );
};
function loadXMPLibrary(){
     if ( !ExternalObject.AdobeXMPScript ){
          try{
               ExternalObject.AdobeXMPScript = new ExternalObject
                                                            ('lib:AdobeXMPScript');
          }catch (e){
               alert( ErrStrs.XMPLIB );
               return false;
          }
     }
     return true;
};
function unloadXMPLibrary(){
   if( ExternalObject.AdobeXMPScript ) {
      try{
         ExternalObject.AdobeXMPScript.unload();
         ExternalObject.AdobeXMPScript = undefined;
      }catch (e){
         alert( ErrStrs.XMPLIB );
      }
   }
};
if( app.documents.length > 0 ){
     var imageRef = new File( "~/Desktop/DSC_5396.NEF" );
     loadXMPLibrary();
     placeFile( imageRef );
     setCommMetadata( decodeURI( imageRef ) );
     var layerXMP = new XMPMeta( app.activeDocument.activeLayer.xmpMetadata.rawData );// create the object
     var comment = layerXMP.getProperty( XMPConst.NS_EXIF, "userComment" );// get comment
}
alert( 'Orginal file is located at ' + comment );

JBL
JBLAuthor
Known Participant
April 30, 2010

Very, very interseting.  I would not have thought that way.

BTW: how are you running this?

As a File>Scripts>Browse...?

Tried to run it that way in CS4 and got this error:

Error 8800: General Photoshop error occurred.  This functionality may not be available in this version of Photoshop.

-the command "Place" is not currenty available.

Line: 42

->   executeAction( charIDToTypeId([Plc ', desc,

DialogModes.No );

Also tried it on a CS5 and got the same result.

This is an interesting approach.

It seems that this way to remember the location of the file could also be used to pull it out of the metadata and re-run it and re-insert the .jpg just in case it has changed.

Paul Riggott
Inspiring
April 30, 2010

It would fail if you didn't change the filename, try changing:

var imageRef = new File( "~/Desktop/DSC_5396.NEF" );
To:-
var imageRef = File.openDialog("Please select File","All Files:*.*;");

It will then prompt for the document to place.