15 Replies Latest reply on Aug 21, 2011 2:24 AM by Paul Riggott

    Modifying capture time

    Lex250

      I would like to use a script to modify the capture time by 1 second in a Photoshop script.

       

      My aim is to use a photoshop droplet to batch process exported files from Ligthroom and use the modification of the capture time as a way to control the sort order in Lightroom (with landscape images sorted before the original and portrait images sorted after to allow correct batch printing from Lightroom)

       

      I can only find reference to captureDate which returns the date in the format yyyymmdd.

       

      Is there a way to identify and modify the capture time in Photoshop scripting?

        • 1. Re: Modifying capture time
          Paul Riggott Level 6

          You could try this....

           

          if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
          var xmp = new XMPMeta( app.activeDocument.xmpMetadata.rawData );
          var DateCreated = xmp.getProperty(XMPConst.NS_XMP, "CreateDate");
          var newDate = new XMPDateTime(DateCreated.toString()).getDate().getTime()+1000;
          xmp.setProperty(XMPConst.NS_XMP, "CreateDate", new XMPDateTime(new Date(newDate)), XMPConst.XMPDATE);
          app.activeDocument.xmpMetadata.rawData = xmp.serialize();
          
          1 person found this helpful
          • 2. Re: Modifying capture time
            Lex250 Level 1

            Thanks for this very helpful response.

            It looks to me as if it is targetting xmp sidecar data associated with a raw file. Is that correct?

            I would be using files exported from Lightroom then batch processed by a Photoshop droplet - so the file format would be jpg.

            Would this script still work in that setting?

            Do you have any alternate suggestions for working with jpg files?

             

            Thanks again for the response.

            • 3. Re: Modifying capture time
              Paul Riggott Level 6

              Hi, this script is for Photoshop and modifies the open document so should work fine called by an action or droplet on any document type.

              • 4. Re: Modifying capture time
                Lex250 Level 1

                Thanks - that works perfectly.

                You've made my day! This has been troubling me for some time.

                • 5. Modified capture time not recognised in Lightroom
                  Lex250 Level 1

                  The script works well and modifies the capture time appearing in Photoshop File Info.

                  However, when I reimport the output file into Lightroom, Lightroom reports the original capture time.

                  When I ask Lightroom to display all EXIF data, it reports the unchanged "Date Time Original" and the modified time as "Date Time Digitized".

                   

                  As the aim of this process was to modify the sort order in Lightroom using Capture Time (which appears to use "Date Time Original"), the process isn't doing what I set out to do.

                   

                  Is there a way to modify the script to modify the field that Lightroom recognises as the "Date Time Original"

                   

                  Thanks again for your help.

                  • 6. Re: Modified capture time not recognised in Lightroom
                    Paul Riggott Level 6

                    I don't know if Lightroom will work from the Photoshop schema, if so this will amend the IPTC Date Created as well as the xmp Date Created.

                     

                    if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                    var xmp = new XMPMeta( app.activeDocument.xmpMetadata.rawData );
                    var DateCreated = xmp.getProperty(XMPConst.NS_XMP, "CreateDate");
                    var newDate = new XMPDateTime(DateCreated.toString()).getDate().getTime()+1000;
                    xmp.setProperty(XMPConst.NS_XMP, "CreateDate", new XMPDateTime(new Date(newDate)), XMPConst.XMPDATE);
                    xmp.setProperty(XMPConst.NS_PHOTOSHOP, "DateCreated", new XMPDateTime(new Date(newDate)), XMPConst.XMPDATE);
                    app.activeDocument.xmpMetadata.rawData = xmp.serialize();
                    

                     


                    Unfortunatley the EXIF schema along with the TIFF schema are read only.

                    The only other way that I can think of is to work with the files on the disc, in this case ExifTool might be the best option.

                    http://www.sno.phy.queensu.ca/~phil/exiftool/

                    1 person found this helpful
                    • 7. Re: Modified capture time not recognised in Lightroom
                      Lex250 Level 1

                      Thanks  - but that still doesn't change the capture time in Lightroom.

                      Lightroom has a menu item to change capture time so it must be editable.

                      As I'm trying to automate the process within a Photoshop script, an external editor or the Lightroom option are less attractive.

                      • 8. Re: Modified capture time not recognised in Lightroom
                        Paul Riggott Level 6

                        I wonder if you are using a PC or Mac?

                        On a PC (I don't like Macs ) you could create a droplet with destination as none then the following script should get the file location and update the time using Exiftool.

                        This example has ExifTool in C:\Exiftool

                         

                        var fileName = decodeURI(app.activeDocument.fullName.fsName);
                        app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                        var ex = new File("/exiftool/changeExif.bat");
                        ex.open('w');
                        ex.writeln('"/Exiftool/exiftool.exe"  "-DateTimeOriginal+=00:00:0 00:00:01"'+ '" '+fileName+'"');
                        ex.close();
                        ex.execute();
                        

                         

                        A simular setup could be used on a Mac but not using a bat file.

                        • 9. Re: Modified capture time not recognised in Lightroom
                          Paul Riggott Level 6

                          There may be another option..?

                          This saves the file as Save For Web, then adds the metadata back to the file with the modified date.

                          The drawback is that the output folder is hard coded, in this case a folder is created off the files folder called converted.

                          You could give it a try?

                           

                          main();
                          function main(){
                          if(!documents.length) return;
                          try{
                          if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                          var xmp = new XMPMeta( app.activeDocument.xmpMetadata.rawData );
                          var DateCreated = xmp.getProperty(XMPConst.NS_EXIF, "DateTimeOriginal");
                          var newDate = new XMPDateTime(DateCreated.toString()).getDate().getTime()+1000;
                          xmp.setProperty(XMPConst.NS_EXIF, "DateTimeOriginal", new XMPDateTime(new Date(newDate)), XMPConst.XMPDATE);
                          var Name = decodeURI(app.activeDocument.name).replace(/\.[^\.]+$/, '');
                          var Path = decodeURI(app.activeDocument.path);
                          var savePath = Folder(Path +"/Converted");
                          if(!savePath.exists) savePath.create();
                          var saveFile = File(savePath +"/"+Name+".jpg");
                          SaveForWeb(saveFile,100);
                          app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                          setXMP(saveFile,xmp);
                          }catch(e){alert(e +" - "+e.line);}
                          }
                          function setXMP( targetFile, XMP){
                              try{
                          if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                           var targetXMPMeta =  XMP ;
                           var xmpFile = new XMPFile( targetFile.fsName, XMPConst.FILE_UNKNOWN, XMPConst.OPEN_FOR_UPDATE | XMPConst.OPEN_USE_SMART_HANDLER ); 
                           if( xmpFile.canPutXMP( targetXMPMeta ) )
                           {
                            xmpFile.putXMP( targetXMPMeta );
                            xmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
                           } else {
                            xmpFile.closeFile();
                           }
                          }catch(e){alert(e +" - "+e.line);}
                          }
                          function SaveForWeb(saveFile,jpegQuality) {
                          var sfwOptions = new ExportOptionsSaveForWeb(); 
                             sfwOptions.format = SaveDocumentType.JPEG; 
                             sfwOptions.includeProfile = false; 
                             sfwOptions.interlaced = 0; 
                             sfwOptions.optimized = true; 
                             sfwOptions.quality = jpegQuality;
                          activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
                          }
                          
                          • 10. Re: Modified capture time not recognised in Lightroom
                            Lex250 Level 1

                            Thanks for your help and responsiveness with this  - it is greatly appreciated.

                             

                            I am running Windows 7 64bit with CS5 64bit

                             

                            Using suggestion 1 with exiftool:

                            - I downloaded the exiftool windows executable only and placed it in c:\\exiftool\exiftool.exe

                            - I ran the scrript from Photoshop with a .jpg image loaded

                            - Photoshop closed the image and there was no error message, but

                            - the file date was not changed and there was no 'changeExif.bat' file in the exiftool folder. A file search of the computer did not find a copy of 'changeExif.bat' in another location.

                            It appeared to me that the bat file was not being created.

                            I thought this may be a Windows UAC problem but there was no change if I opened Photoshop as administrator

                             

                            Using option 2 - saving as jpg for web and adding exif data back

                            - I ran the scrript from Photoshop with a .jpg image loaded

                            - Photoshop closed the image but then returned an error message "Error: XMP exception: OpenFile returned false -24"

                            - there was a new file in the converted folder but the exif data was blank.

                             

                            It seems like the solution is near but still elusive, at least to my limited skills.

                            • 11. Re: Modified capture time not recognised in Lightroom
                              Paul Riggott Level 6

                              I have found the error with the ExifTool script, it was a space out.

                              This should work now.

                               

                              try{
                              var fileName = decodeURI(app.activeDocument.fullName.fsName);
                              app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                              var ex = new File("/exiftool/changeExif.bat");
                              ex.open('w');
                              ex.writeln('"/Exiftool/exiftool.exe"  "-DateTimeOriginal+=00:00:00 00:00:01"'+ ' "'+fileName+'"');
                              ex.close();
                              ex.execute();
                              }catch(e){alert(e+" - "+e.line);}
                              

                               

                               

                              Yes I am now getting the same error as you with the second script, so I will try to get it working again.

                              • 12. Re: Modified capture time not recognised in Lightroom
                                Paul Riggott Level 6

                                Ok, I have found the error with the second script, actually it is a setting in Save For Web.

                                You will need to open any document, File - Save For Web and Devices, open the fly-out menu

                                Pic1.jpg

                                Then navigate to this screen...

                                Pic2.jpg

                                When this box is ticked the output filename is changed, all spaces are converted to a hyphon , that's why the script couldn't find the file.

                                 

                                I have updated the script to use a better Save for Web....

                                 

                                 

                                main();
                                function main(){
                                if(!documents.length) return;
                                try{
                                if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                                var xmp = new XMPMeta( app.activeDocument.xmpMetadata.rawData );
                                var DateCreated = xmp.getProperty(XMPConst.NS_EXIF, "DateTimeOriginal");
                                var newDate = new XMPDateTime(DateCreated.toString()).getDate().getTime()+1000;
                                xmp.setProperty(XMPConst.NS_EXIF, "DateTimeOriginal", new XMPDateTime(new Date(newDate)), XMPConst.XMPDATE);
                                var Name = decodeURI(app.activeDocument.name).replace(/\.[^\.]+$/, '');
                                var Path = decodeURI(app.activeDocument.path);
                                var savePath = Folder(Path +"/Converted");
                                if(!savePath.exists) savePath.create();
                                var saveFile = File(savePath +"/"+Name+".jpg");
                                saveForWeb(saveFile,100);
                                app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                                setXMP(saveFile,xmp);
                                }catch(e){alert(e +" - "+e.line);}
                                }
                                function setXMP( targetFile, XMP){
                                    try{
                                if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
                                 var targetXMPMeta =  XMP ;
                                 var xmpFile = new XMPFile( targetFile.fsName, XMPConst.FILE_UNKNOWN, XMPConst.OPEN_FOR_UPDATE | XMPConst.OPEN_USE_SMART_HANDLER ); 
                                 if( xmpFile.canPutXMP( targetXMPMeta ) )
                                 {
                                  xmpFile.putXMP( targetXMPMeta );
                                  xmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
                                 } else {
                                  xmpFile.closeFile();
                                 }
                                }catch(e){alert(e +" - "+e.line);}
                                }
                                function saveForWeb(saveFile,Quality) {
                                    var desc2 = new ActionDescriptor();
                                        var desc3 = new ActionDescriptor();
                                        desc3.putEnumerated( charIDToTypeID('Op  '), charIDToTypeID('SWOp'), charIDToTypeID('OpSa') );
                                        desc3.putBoolean( charIDToTypeID('DIDr'), false );
                                        desc3.putPath( charIDToTypeID('In  '), new File(saveFile ) );
                                        desc3.putEnumerated( charIDToTypeID('Fmt '), charIDToTypeID('IRFm'), charIDToTypeID('JPEG') );
                                        desc3.putBoolean( charIDToTypeID('Intr'), false );
                                        desc3.putInteger( charIDToTypeID('Qlty'), Quality );
                                        desc3.putInteger( charIDToTypeID('QChS'), 0 );
                                        desc3.putInteger( charIDToTypeID('QCUI'), 0 );
                                        desc3.putBoolean( charIDToTypeID('QChT'), false );
                                        desc3.putBoolean( charIDToTypeID('QChV'), false );
                                        desc3.putBoolean( charIDToTypeID('Optm'), true );
                                        desc3.putInteger( charIDToTypeID('Pass'), 1 );
                                        desc3.putDouble( charIDToTypeID('blur'), 0.000000 );
                                        desc3.putBoolean( charIDToTypeID('EICC'), false );
                                        desc3.putBoolean( charIDToTypeID('Mtt '), false );
                                        desc3.putInteger( charIDToTypeID('MttR'), 255 );
                                        desc3.putInteger( charIDToTypeID('MttG'), 255 );
                                        desc3.putInteger( charIDToTypeID('MttB'), 255 );
                                        desc3.putBoolean( charIDToTypeID('SHTM'), false );
                                        desc3.putBoolean( charIDToTypeID('SImg'), true );
                                        desc3.putEnumerated( charIDToTypeID('SWsl'), charIDToTypeID('STsl'), charIDToTypeID('SLAl') );
                                        desc3.putEnumerated( charIDToTypeID('SWch'), charIDToTypeID('STch'), charIDToTypeID('CHsR') );
                                        desc3.putEnumerated( charIDToTypeID('SWmd'), charIDToTypeID('STmd'), charIDToTypeID('MDNn') );
                                        desc3.putBoolean( charIDToTypeID('ohXH'), false );
                                        desc3.putBoolean( charIDToTypeID('ohIC'), true );
                                        desc3.putBoolean( charIDToTypeID('ohAA'), true );
                                        desc3.putBoolean( charIDToTypeID('ohQA'), true );
                                        desc3.putBoolean( charIDToTypeID('ohCA'), false );
                                        desc3.putBoolean( charIDToTypeID('ohIZ'), true );
                                        desc3.putEnumerated( charIDToTypeID('ohTC'), charIDToTypeID('SToc'), charIDToTypeID('OC03') );
                                        desc3.putEnumerated( charIDToTypeID('ohAC'), charIDToTypeID('SToc'), charIDToTypeID('OC03') );
                                        desc3.putInteger( charIDToTypeID('ohIn'), -1 );
                                        desc3.putEnumerated( charIDToTypeID('ohLE'), charIDToTypeID('STle'), charIDToTypeID('LE03') );
                                        desc3.putEnumerated( charIDToTypeID('ohEn'), charIDToTypeID('STen'), charIDToTypeID('EN00') );
                                        desc3.putBoolean( charIDToTypeID('olCS'), false );
                                        desc3.putEnumerated( charIDToTypeID('olEC'), charIDToTypeID('STst'), charIDToTypeID('ST00') );
                                        desc3.putEnumerated( charIDToTypeID('olWH'), charIDToTypeID('STwh'), charIDToTypeID('WH01') );
                                        desc3.putEnumerated( charIDToTypeID('olSV'), charIDToTypeID('STsp'), charIDToTypeID('SP04') );
                                        desc3.putEnumerated( charIDToTypeID('olSH'), charIDToTypeID('STsp'), charIDToTypeID('SP04') );
                                            var list1 = new ActionList();
                                                var desc4 = new ActionDescriptor();
                                                desc4.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC00') );
                                            list1.putObject( charIDToTypeID('SCnc'), desc4 );
                                                var desc5 = new ActionDescriptor();
                                                desc5.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC19') );
                                            list1.putObject( charIDToTypeID('SCnc'), desc5 );
                                                var desc6 = new ActionDescriptor();
                                                desc6.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC28') );
                                            list1.putObject( charIDToTypeID('SCnc'), desc6 );
                                                var desc7 = new ActionDescriptor();
                                                desc7.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC24') );
                                            list1.putObject( charIDToTypeID('SCnc'), desc7 );
                                                var desc8 = new ActionDescriptor();
                                                desc8.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC24') );
                                            list1.putObject( charIDToTypeID('SCnc'), desc8 );
                                                var desc9 = new ActionDescriptor();
                                                desc9.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC24') );
                                            list1.putObject( charIDToTypeID('SCnc'), desc9 );
                                        desc3.putList( charIDToTypeID('olNC'), list1 );
                                        desc3.putBoolean( charIDToTypeID('obIA'), false );
                                        desc3.putString( charIDToTypeID('obIP'), "" );
                                        desc3.putEnumerated( charIDToTypeID('obCS'), charIDToTypeID('STcs'), charIDToTypeID('CS01') );
                                            var list2 = new ActionList();
                                                var desc10 = new ActionDescriptor();
                                                desc10.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC01') );
                                            list2.putObject( charIDToTypeID('SCnc'), desc10 );
                                                var desc11 = new ActionDescriptor();
                                                desc11.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC20') );
                                            list2.putObject( charIDToTypeID('SCnc'), desc11 );
                                                var desc12 = new ActionDescriptor();
                                                desc12.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC02') );
                                            list2.putObject( charIDToTypeID('SCnc'), desc12 );
                                                var desc13 = new ActionDescriptor();
                                                desc13.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC19') );
                                            list2.putObject( charIDToTypeID('SCnc'), desc13 );
                                                var desc14 = new ActionDescriptor();
                                                desc14.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC06') );
                                            list2.putObject( charIDToTypeID('SCnc'), desc14 );
                                                var desc15 = new ActionDescriptor();
                                                desc15.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC24') );
                                            list2.putObject( charIDToTypeID('SCnc'), desc15 );
                                                var desc16 = new ActionDescriptor();
                                                desc16.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC24') );
                                            list2.putObject( charIDToTypeID('SCnc'), desc16 );
                                                var desc17 = new ActionDescriptor();
                                                desc17.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC24') );
                                            list2.putObject( charIDToTypeID('SCnc'), desc17 );
                                                var desc18 = new ActionDescriptor();
                                                desc18.putEnumerated( charIDToTypeID('ncTp'), charIDToTypeID('STnc'), charIDToTypeID('NC22') );
                                            list2.putObject( charIDToTypeID('SCnc'), desc18 );
                                        desc3.putList( charIDToTypeID('ovNC'), list2 );
                                        desc3.putBoolean( charIDToTypeID('ovCM'), false );
                                        desc3.putBoolean( charIDToTypeID('ovCW'), true );
                                        desc3.putBoolean( charIDToTypeID('ovCU'), false );
                                        desc3.putBoolean( charIDToTypeID('ovSF'), true );
                                        desc3.putBoolean( charIDToTypeID('ovCB'), true );
                                        desc3.putString( charIDToTypeID('ovSN'), "images" );
                                    desc2.putObject( charIDToTypeID('Usng'), stringIDToTypeID('SaveForWeb'), desc3 );
                                    executeAction( charIDToTypeID('Expr'), desc2, DialogModes.NO );
                                };
                                


                                Hope one of these methods work

                                • 13. Re: Modified capture time not recognised in Lightroom
                                  Lex250 Level 1

                                  Wow - I'm very impressed by the time and effort that you've put into answering this problem - it's very much appreciated.

                                   

                                  I tried the exiftool solution and got it to work by modifying the content written into the batch file to refer to "c:\\\exiftool\\exiftool.exe" rather than "/exiftool/exiftool.exe". This solution did modify the capture time but in Lightroom each file had an error indicating conflicting xmp data that requires a manual process to resolve the conflict for each file. This occurs because the photo already existed in Lightroom before running the script. I expect that I can resolve that by importing the photos into Lightroom as a manual step only after completion of the script and time change.

                                   

                                  I've only briefly tried the Save to Web option but that also worked.

                                   

                                  I'll try to work out the best solution to integrate into my workflow and existing scripting and let you know the outcome. However, I won't have much time available to do so in the next few days.

                                   

                                  Thanks again - I'm hopeful that this is now resolved.

                                  • 14. Re: Modified capture time not recognised in Lightroom
                                    Lex250 Level 1

                                    Thanks so much for your help.

                                    This is now all working as I'd hoped.

                                     

                                    I'm using the Export to Web option and then using the autoimport function of Lightroom to import the newly created jpg files with modified xmp creation time.

                                    I've been able to integrate this script to create a single script and Photoshop droplet. The exiftool option also works but would be a bit more clumsy in my workflow.

                                     

                                    My workflow is

                                    - export from Lightroom to temp folder and initiate Photoshop droplet.

                                    - use the droplet to modify the file and overwrite the original file with a modified version

                                    - the droplet then saves a new Save for Web jpg file in the temp\converted folder and adds back modified xmp data

                                    - Lightroom's autoimport feature automatically imports files from the temp\converted folder

                                    The only additional manual components are to delete the contents of the temp folder and to turn on and off the autooimport function.

                                    • 15. Re: Modified capture time not recognised in Lightroom
                                      Paul Riggott Level 6

                                      Glad to hear you have a workable workflow!