Adding a "Days Since" Count via Watermark

I’m using Retrobatch to construct an animated transition timeline. I can pretty easily add the date to each frame, but what I’d really like to do is add a days count from the first: Day 0, Day 1, Day 2, Day 3, etc etc. I don’t see how to do that, and I can’t quite figure out how to make a JavaScript node that can read the capture date (to calculate Days Since) and then send that string to the Watermark node.

Am I barking up the wrong tree?

Thanks!
—Mims

This is possible with a little bit of JavaScript. I’ve attached a sample workflow demonstrating this.

DaysSinceWatermark.retrobatch (7.5 KB)

The workflow goes:

Read Folder ▸ JavaScript ▸ Text Watermark ▸ Write Images

There are a couple of things going on here, and I’ll describe them below. First up is the JavaScript, with comments inline:

// This is the standard "hey do something with an image" callback.
function processAsset(document, jsnode, asset) {
    
    // This is the date that we want to calculate our time differences from.
    var sinceDate = new Date('November 11, 2023');
    
    // Next up, we first look for the date time metadata in the image - first in the TIFF dictionary and then in the EXIF dictionary. If the date isn't around, then we don't do our watermark.
    
    var date = asset.metaValueForPropertyName_inMetaDictionaryName(kCGImagePropertyTIFFDateTime, kCGImagePropertyTIFFDictionary)
    date = date ? date : asset.metaValueForPropertyName_inMetaDictionaryName(kCGImagePropertyExifDateTimeOriginal, kCGImagePropertyExifDictionary)
    
    if (date) { // We're only in here if we have a date.
        
        // Parse the date string into a JavaScript date object:
        var imgDate = parseDate(date);
        
        // Calcuate the time difference and then multiply it by the number of milliseconds in a day.
        var noDays = Math.round((imgDate - sinceDate) / (1000 * 60 * 60 * 24));
        
        // Put the resulting calculation in a string to use in the Watermark node.
        asset.setUserValue_forKey(`Day ${noDays}`, "DaysSinceKey");
    }
    
    return true;
}

/* Parse date string in YYYY-MM-DD hh:mm:ss format
** separator can be any non-digit character
** e.g. 2017:03:09 14:49:21
*/
function parseDate(s) {
  var b = s.split(/\D/);
  return new Date(b[0],b[1]-1,b[2],b[3],b[4],b[5]);
}

The in the Text Watermark node we have this:

The little $userValue.DaysSinceKey$ tells the watermark node to get the text that we set in our JavaScript node, and display that. And that’s it!

Thanks, I’ll give this a try! :smiley:

This looks like it’s calculating off of the save date and not the capture date. Is there a way to grab the capture date? Thanks so much! :smiley:

You would use the kCGImagePropertyExifDateTimeDigitized key instead of the kCGImagePropertyExifDateTimeOriginal or kCGImagePropertyTIFFDateTime to see if that has the value you’re looking for.

Modify the code to look like:

var date = asset.metaValueForPropertyName_inMetaDictionaryName(kCGImagePropertyExifDateTimeDigitized, kCGImagePropertyExifDictionary)

But, it’s also possible that an image editor is changing the create date of the image instead of retaining what the original date is (in the case that you are modifying the images). RB will just report what it finds in the meta data.