Copy link to clipboard
Copied
I am very new to working with metadata. I have a microsoft excel file with the IPTC Core fields I need for each image file.
(Creator, Headline, Description, Keywords, Title, Job Identifier, Credit Line, Source, Rights Usage Terms, Copyright Status and Copyright Notice)
Is there a way to get the metadata into the files without having to copy from a cell into each metadata field individually?
I am hoping some for sort of script, possibly...
Also, if only ONE of these fields needed updating in all of the files (i.e. Rights Usage Terms) can that be done?
I have Bridge 5.1 (and earlier versions CS3/CS4)
Perhaps try tab delimited format instead of comma separated value format.
Edit – Paul Riggott originally wrote the following instructions:
...
N.B. The first field in the input file MUST be the filename only IE:- CRW_0001.jpg
This script will allow you to choose the fields and order they are in within either your CSV or TEXT file so that you can input your metadata.
Fields available are:-
Keywords 1 - These are Keywords that are in ONE field seperated by semicolons
Keywords 2 - These are Key
Copy link to clipboard
Copied
Hi Stephen,
Thank you for your reply.
The script is here
exiftool Application Documentation
Unfortunately IT at work doesn't let us use ExifTool ..
Copy link to clipboard
Copied
I.T. dept’s annoy me sometimes! I am sure that your I.T. dept will have no problems in doing all of this via a script then… hang on, that is why you are here. :]
Try this:
Copy link to clipboard
Copied
Thanks again Stephen,
It looks great - just tried it.
However I got data on spreadsheet and need to put these data on the images. I don't think VRA allow me to do that..
Copy link to clipboard
Copied
It should, it’s not called the Import-Export tool for nothing!
However, I don’t know if it supports the field you are trying to add to the DIY Metadata script.
Copy link to clipboard
Copied
I have added the field for you...
////////////////////////////
#target bridge
//written by Paul Riggott
if( BridgeTalk.appName == "bridge" ) {
if(!MenuElement.find("myMetaData")){
var newMenu = new MenuElement( "menu", "MetaData", "after Help", "myMetaData" );
}
var newCommand = new MenuElement( "command", "DIY Custom Metadata", "at the end of myMetaData" , "xx1C" );
}
newCommand.onSelect = function () {
DIYMetadata();
}
function DIYMetadata(){
var win = new Window( 'dialog', 'With Compliments' );
var inputFile ='';
win.alignChildren=["row","bottom"];
win.g1 = win.add('group');
win.title = win.g1.add('statictext',undefined,'Bridge Input Metadata');
win.title.alignment="bottom";
win.title.graphics.font = ScriptUI.newFont("Georgia","BOLDITALIC",26);
win.title.helpTip="Written by Paul Riggott";
win.g0 = win.add('group');
win.g0.orientation = "row";
win.p1= win.g0.add("panel", undefined, "Select Fields", {borderStyle:"black"});
win.p1.helpTip="At least one field is required!";
win.p1.preferredSize=[150,470];
win.p1.alignChildren="column";
win.g5 =win.p1.add('group');
win.g5.orientation="column";
win.g5.alignChildren = "left";
win.g5.spacing=10;
var Options=['Keywords 1','Keywords 2','Description','Headline','Title','Instructions','Date Created','Location','City','Country','Rating','Copyright Notice','Creator','Label','Usage Terms','Credit','Source','Job Identifier','SubjectCode'];
win.g5.cb1 = win.g5.add('checkbox',undefined,'Keywords 1');
win.g5.cb1.helpTip="Keywords in one field seperated by a semicolon ';'";
win.g5.cb2 = win.g5.add('checkbox',undefined,'Keywords 2');
win.g5.cb2.helpTip="Keywords in seperate fields\rThese must be last in the list!";
win.g5.cb3 = win.g5.add('checkbox',undefined,'Description');
win.g5.cb4 = win.g5.add('checkbox',undefined,'Headline');
win.g5.cb5 = win.g5.add('checkbox',undefined,'Title');
win.g5.cb6 = win.g5.add('checkbox',undefined,'Instructions');
win.g5.cb7 = win.g5.add('checkbox',undefined,'Date Created');
win.g5.cb8 = win.g5.add('checkbox',undefined,'Location');
win.g5.cb9 = win.g5.add('checkbox',undefined,'City');
win.g5.cb10 = win.g5.add('checkbox',undefined,'Country');
win.g5.cb11 = win.g5.add('checkbox',undefined,'Rating');
win.g5.cb12 = win.g5.add('checkbox',undefined,'Copyright Notice');
win.g5.cb13 = win.g5.add('checkbox',undefined,'Creator');
win.g5.cb14 = win.g5.add('checkbox',undefined,'Label');
win.g5.cb15 = win.g5.add('checkbox',undefined,'Usage Terms');
win.g5.cb16 = win.g5.add('checkbox',undefined,'Credit');
win.g5.cb17 = win.g5.add('checkbox',undefined,'Source');
win.g5.cb18 = win.g5.add('checkbox',undefined,'Job Identifier');
win.g5.cb19 = win.g5.add('checkbox',undefined,'Subject Code');
win.p2= win.g0.add("panel", undefined, "Order Of Fields In Input File", {borderStyle:"black"});
win.p2.helpTip="Shuffle as required";
win.p2.preferredSize=[150,470];
win.g10 =win.p2.add('group');
win.g10.lb1 = win.g10.add('listbox');
win.g10.lb1.preferredSize=[130,400];
win.g10a =win.p2.add('group');
win.g10a.orientation = "row";
win.g10a.bu1 = win.g10a.add('button',undefined,"Move Up");
win.p3= win.g0.add("panel", undefined, "Input Options", {borderStyle:"black"});
win.p3.helpTip="First field in the input file must be the filename only!";
win.p3.preferredSize=[150,470];
win.g15 =win.p3.add('group');
win.g15.orientation = "column";
win.g15.alignChildren = "left";
win.g15.cb1 = win.g15.add('checkbox',undefined,'Remove Header Line');
win.g15.cb1.helpTip="The first line of the input file\rwill be removed";
win.g15.rb1 = win.g15.add('radiobutton',undefined,'CSV Comma Delimited');
win.g15.rb2 = win.g15.add('radiobutton',undefined,'Text Tab Delimited');
win.g15.rb1.value=true;
win.g15.cb2 = win.g15.add('checkbox',undefined,'Use Files in Sub Folders');
win.g15.cb3 = win.g15.add('checkbox',undefined,'Copyright all files');
win.g10a.bu1.onClick = function(){
if(win.g10.lb1.selection == null) return;
var itemNames = win.g10.lb1.selection;
var pos =itemNames.index-1;
if(pos>-1){
var tmp =win.g10.lb1.selection.text;
win.g10.lb1.remove(itemNames.index);
win.g10.lb1.add("item",tmp,pos);
win.g10.lb1.selection=pos;
}
}
win.g10a.bu2 = win.g10a.add('button',undefined,"Move Down");
win.g10a.bu2.onClick = function(){
if(win.g10.lb1.selection == null) return;
var itemNames = win.g10.lb1.selection;
var pos =itemNames.index+1;
if(pos<win.g10.lb1.items.length){
var tmp =win.g10.lb1.selection.text;
win.g10.lb1.remove(itemNames.index);
win.g10.lb1.add("item",tmp,pos);
win.g10.lb1.selection=pos;
}
}
win.g20 = win.add('group');
win.p4= win.g20.add("panel", undefined, "Select Input File", {borderStyle:"black"});
win.p4.orientation = "row";
win.p4.spacing=40;
win.p4.preferredSize=[550,40];
win.p4.et1 = win.p4.add('edittext');
win.p4.et1.enabled=false;
win.p4.et1.preferredSize=[400,20];
win.p4.bu1 = win.p4.add('button',undefined,'Browse');
win.p4.bu1.onClick=function(){
if(win.g15.rb1.value){
inputFile = File.openDialog("Open Keywords File","CSV File(*.csv):*.csv;");
}else{
inputFile = File.openDialog("Open Keywords File","TXT File(*.txt):*.txt;");
}
if(inputFile != null) win.p4.et1.text = decodeURI(inputFile.fsName);
}
win.g100 = win.add('group');
win.g100.spacing=20;
win.g100.orientation = "row";
win.g100.bu1 = win.g100.add('button',undefined,"Process");
win.g100.bu1.preferredSize=[250,40];
win.g100.bu2 = win.g100.add('button',undefined,"Cancel");
win.g100.bu2.preferredSize=[250,40];
win.layout.layout();
win.g100.bu1.onClick=function(){
var Items = win.g10.lb1.items.length;
if(Items < 1) {
alert("At least one field is required!");
return;
}
if(inputFile == null) {
alert("Input file has not been selected!");
return;
}
if(!inputFile.exists) {
alert("Input file has not been selected!");
return;
}
var keyCount=0;
var key2 = 99;
var List = win.g10.lb1.items.toString().split(',');
for(var x in List){
if(List
.toString().match(/^Keywords/)) keyCount++; if(List
.toString().match(/^Keywords 2/)) key2 = x; }
if(keyCount >1) {
alert("Only one set of Keywords allowed!");
return;
}
if(key2 != 99){
if(key2 != (win.g10.lb1.items.length-1)){
win.g5.cb2.value=false;
win.g5.cb2.onClick();
win.g5.cb2.value=true;
win.g5.cb2.onClick();
alert("These keywords must be last in the list please\rcheck if the listing is now correct!");
return;
}
}
win.close(1);
Process();
};
win.g5.cb1.onClick = function(){
if(win.g5.cb1.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb2.onClick = function(){
if(win.g5.cb2.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb3.onClick = function(){
if(win.g5.cb3.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb4.onClick = function(){
if(win.g5.cb4.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb5.onClick = function(){
if(win.g5.cb5.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb6.onClick = function(){
if(win.g5.cb6.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb7.onClick = function(){
if(win.g5.cb7.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb8.onClick = function(){
if(win.g5.cb8.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb9.onClick = function(){
if(win.g5.cb9.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb10.onClick = function(){
if(win.g5.cb10.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb11.onClick = function(){
if(win.g5.cb11.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb12.onClick = function(){
if(win.g5.cb12.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb13.onClick = function(){
if(win.g5.cb13.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb14.onClick = function(){
if(win.g5.cb14.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb15.onClick = function(){
if(win.g5.cb15.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb16.onClick = function(){
if(win.g5.cb16.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb17.onClick = function(){
if(win.g5.cb17.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb18.onClick = function(){
if(win.g5.cb18.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.g5.cb19.onClick = function(){
if(win.g5.cb19.value) {
win.g10.lb1.add("item",this.text);
var Count = win.g10.lb1.items.toString().split(',').length;
win.g10.lb1.selection=Number(Count-1);
}else{
var Items = win.g10.lb1.items.toString().split(',');
for(var a in Items){
if(Items.toString().match(this.text)){
win.g10.lb1.remove(Number(a));
}
}
}
}
win.graphics.backgroundColor = win.graphics.newBrush(win.graphics.BrushType.SOLID_COLOR, [1.00, 1.00, 1.00, 1]);
win.center();
win.show();
function Process(){
var copyRight = win.g15.cb3.value;
folders=[];
if(win.g15.cb2.value){//Use subfolders
var topLevel = Folder(app.document.presentationPath);
folders = FindAllFolders(topLevel, folders);
folders.unshift(topLevel);
}
var OrderList = win.g10.lb1.items.toString().split(',');
var Path =app.document.presentationPath;
var errorLog = File(Path +"/Error Log.txt");
loadXMPLib();
inputFile.open('r');
if(win.g15.cb1.value) inputFile.readln();
var datFile=[];
while(!inputFile.eof){
var line = inputFile.readln();
if(line.length > 5) datFile.push(line);
}
inputFile.close();
errorLog.open('w');
errorLog.writeln("Processing :: "+decodeURI(inputFile.fsName) +" Total Files = "+datFile.length+"\r\r");
errorLog.close();
for(var t in datFile){
var str=datFile
; if(win.g15.rb2.value){
str= str.split('\t');
}else{
str= str.split(',');
}
if(!win.g15.cb2.value){//Use subfolders
var fileName = new File(Path+"/"+ str.shift());
}else{
var nextFile = str.shift();
for(var g in folders){
var fileName = new File(folders
+ "/" + nextFile); if(fileName.exists) break;
}
if(!fileName.exists) fileName = new File(Path + "/" + nextFile);
}
var Keys=''; var Desc =''; var Head = ''; var Title =''; var Instructions =''; var CopyInfo =''; var Creator='';
var Location =''; var scriptDate = ''; var d = ''; var City =''; var Country = ''; var Rating = 0; var Label='';var Usage='';var Credit=''; var Source='';var JobId='';var subCode='';
var doKeys = doDesc = doHead = doTitle = doInst = doDate = doLoc = doCity = doCountry = doRating = doCopyInfo =doCreator = doLabel = doUsage = doCredit = doSource = doJobId = doSubCode =false;
//var Options=['Keywords 1','Keywords 2','Description','Headline','Title','Instructions','Date Created','Location','City','Country','Rating','Copyright Notice','Creator','Label','Usage Terms','Credit','Source','Job Identifier','Subject Code'];
for(var a in OrderList){
switch(OrderList.toString()){
case 'Keywords 1' : Keys =str.shift(); Keys = Keys.split(";") doKeys = true; break;
case 'Keywords 2' : Keys = str; doKeys = true; break;
case 'Description' : Desc = str.shift().toString().replace(/\"/g,''); doDesc = true; break;
case 'Copyright Notice' : CopyInfo = str.shift().toString().replace(/\"/g,''); doCopyInfo = true; break;
case 'Headline' : Head = str.shift().toString().replace(/\"/g,''); doHead = true; break;
case 'Creator' : Creator = str.shift().toString().replace(/\"/g,''); doCreator = true; break;
case 'Title' : Title = str.shift().toString().replace(/\"/g,''); doTitle = true; break;
case 'Instructions' : Instructions = str.shift().toString().replace(/\"/g,''); doInst = true; break;
case 'Date Created' : scriptDate = str.shift().toString().replace(/\"/g,'');
d = new XMPDateTime(new Date(Date.parse (scriptDate))); doDate = true; break;
case 'Location' : Location = str.shift().toString().replace(/\"/g,''); doLoc = true; break;
case 'City' : City = str.shift().toString().replace(/\"/g,''); doCity = true; break;
case 'Country' : Country = str.shift().toString().replace(/\"/g,''); doCountry = true; break;
case 'Rating' : Rating = Number(str.shift()); doRating = true; break;
case 'Label' : Label = str.shift().toString().replace(/\"/g,''); doLabel = true; break;
case 'Usage Terms' : Usage= str.shift().toString().replace(/\"/g,''); doUsage = true; break;
case 'Credit' : Credit = str.shift().toString().replace(/\"/g,''); doCredit = true; break;
case 'Source' : Source = str.shift().toString().replace(/\"/g,''); doSource = true; break;
case 'Job Identifier' : JobId = str.shift().toString().replace(/\"/g,''); doJobId = true; break;
case 'Subject Code' : subCode = str.shift().toString().replace(/\"/g,''); doSubCode = true; break;
default : break;
}
}
if(fileName.exists){
var thumb = new Thumbnail(fileName);
if(thumb.hasMetadata){
var selectedFile = thumb.spec;
var myXmpFile = new XMPFile( selectedFile.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE);
var myXmp = myXmpFile.getXMP();
if(doLabel){
try{
switch(Label.toString().toLowerCase()){
case 'select' : thumb.label='Select'; break;
case 'second' : thumb.label='Second'; break;
case 'approved' : thumb.label='Approved'; break;
case 'review' : thumb.label='Review'; break;
case 'to do' : thumb.label='To Do'; break;
default : break;
}
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Unable to Copyright");}
}
if(copyRight){
try{
myXmp.setProperty( XMPConst.NS_XMP_RIGHTS, "Marked",true, XMPConst.STRING);
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Unable to Copyright");}
}
if(doCreator){
try{
myXmp.deleteProperty(XMPConst.NS_DC, "creator");
myXmp.appendArrayItem(XMPConst.NS_DC, "creator", Creator, 0,XMPConst.ARRAY_IS_ORDERED);
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Unable to add Creator");}
}
if(doCopyInfo){
try{
myXmp.deleteProperty(XMPConst.NS_DC, "rights");
myXmp.setLocalizedText( XMPConst.NS_DC, "rights", null, "x-default", CopyInfo );
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad Copyright Info : "+CopyInfo);}
}
if(doRating){
try{
myXmp.deleteProperty(XMPConst.NS_XMP, "Rating");
myXmp.setProperty(XMPConst.NS_XMP, "Rating", Number(Rating));
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad Rating : "+Rating);}
}
if(doInst){
try{
myXmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "Instructions");
myXmp.setProperty(XMPConst.NS_PHOTOSHOP, "Instructions", Instructions);
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad Instruction : "+Instructions);}
}
if(doCredit){
try{
myXmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "Credit");
myXmp.setProperty(XMPConst.NS_PHOTOSHOP, "Credit", Credit);
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad Credit: "+Credit);}
}
if(doSource){
try{
myXmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "Source");
myXmp.setProperty(XMPConst.NS_PHOTOSHOP, "Source", Source);
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad Source: "+ Source);}
}
if(doJobId){
try{
myXmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "TransmissionReference");
myXmp.setProperty(XMPConst.NS_PHOTOSHOP, "TransmissionReference", JobId);
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad Job Id: "+ JobId);}
}
if(doCountry){
try{
myXmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "Country");
myXmp.setProperty(XMPConst.NS_PHOTOSHOP, "Country", Country);
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad Country : "+Country);}
}
if(doCity){
try{
myXmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "City");
myXmp.setProperty(XMPConst.NS_PHOTOSHOP, "City", City);
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad City : "+City);}
}
if(doDesc){
try{
myXmp.deleteProperty(XMPConst.NS_DC, "description");
myXmp.setLocalizedText( XMPConst.NS_DC, "description", null, "x-default", Desc );
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad Description : "+Desc);}
}
if(doLoc){
try{
myXmp.deleteProperty(XMPConst.NS_IPTC_CORE, "Location");
myXmp.setProperty(XMPConst.NS_IPTC_CORE, "Location",Location);
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad Location : "+Location);}
}
if(Head){
try{
myXmp.deleteProperty(XMPConst.NS_PHOTOSHOP, "Headline");
myXmp.setProperty(XMPConst.NS_PHOTOSHOP, "Headline", Head);
}catch(e){sendError(errorLog,decodeURI(fileName)+" :: Bad Headline : "+Head);}
}
if(doDate){
try{
if(!d.toString().match(/^0000/)) {
myXmp.setProperty(XMPConst.NS_PHOTOSHOP, "DateCreated", d, XMPConst.XMPDATE);
}else{sendError(errorLog,decodeURI(fileName)+ " :: Bad date : "+scriptDate);}
}catch(e){sendError(errorLog,decodeURI(fileName)+ " :: Bad date : "+scriptDate);}
}
if(doTitle){
try{
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");
}catch(e){sendError(errorLog,decodeURI(fileName)+" :: Bad Title : "+Title);}
}
if(doUsage){
try{
myXmp.deleteProperty(XMPConst.NS_XMP_RIGHTS, "UsageTerms");
myXmp.setLocalizedText( XMPConst.NS_XMP_RIGHTS, "UsageTerms", null, "x-default", Usage);
}catch(e){sendError(errorLog,decodeURI(fileName)+" :: Bad Usage : "+Usage);}
}
if(doKeys){
try{
// myXmp.deleteProperty(XMPConst.NS_DC,'subject');
for(var s in Keys){
myXmp.appendArrayItem(XMPConst.NS_DC, "subject", Keys
, 0,XMPConst.PROP_IS_ARRAY);}
}catch(e){sendError(errorLog,decodeURI(fileName)+" :: Bad Keyword : "+Keys.toString());}
}
if(doSubCode){
try{
myXmp.appendArrayItem("http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/", "SubjectCode", subCode.toString(), 0,XMPConst.PROP_IS_ARRAY);
}catch(e){sendError(errorLog,decodeURI(fileName)+" :: Bad Subject Code : "+ subCode.toString());}
}
if (myXmpFile.canPutXMP(myXmp)) {
myXmpFile.putXMP(myXmp);
myXmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
} else{alert("shit has happened!");}
}
}else{
errorLog.open('e');
errorLog.seek(0,2);
errorLog.writeln(decodeURI(fileName) + " does not exist!");
errorLog.close();
}
}
errorLog.execute();
}
function sendError(errorLog,errorMessage){
errorLog.open('e');
errorLog.seek(0,2);
errorLog.writeln(errorMessage);
errorLog.close();
}
function FindAllFolders( srcFolderStr, destArray) {
var fileFolderArray = Folder( srcFolderStr ).getFiles();
for ( var i = 0; i < fileFolderArray.length; i++ ) {
var fileFoldObj = fileFolderArray;
if ( fileFoldObj instanceof File ) {
} else {
destArray.push( Folder(fileFoldObj) );
FindAllFolders( fileFoldObj.toString(), destArray );
}
}
return destArray;
}
function loadXMPLib(){
if (ExternalObject.AdobeXMPScript == undefined) {
ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
}
}
function unloadXMPLib(){
if( ExternalObject.AdobeXMPScript ) {
try{
ExternalObject.AdobeXMPScript.unload();
ExternalObject.AdobeXMPScript = undefined;
}catch (e){ }
}
}
}
Copy link to clipboard
Copied
Copy link to clipboard
Copied
OMG! Thank you so much!!!!!!
Copy link to clipboard
Copied
Hiya,
I have found a problem.. Not sure if it's the nature of Bridge or script.
When the Title includes ' , ' , texts after ' , ' goes to Job ID...
i.e.
Title : Edge of Seventeen, The
becomes
Title: Edge of Seventeen
Job ID : The
And Job ID is gone
Any fix for this? I can not change the original title, because that's how they are in our system...
Thanks!
Copy link to clipboard
Copied
Were you using a Comma Separated Value (.csv) file as the import source?
If so, then you should use a Tab Delimited Value (.txt) instead.
How many files contain incortext metadata that will need to be fixed?
Copy link to clipboard
Copied
Yes that's correct.
Is using .txt more complex?
I never used .txt for this..
Copy link to clipboard
Copied
I have not used this either, however it is a common enough issue with importing data (database imports, variable data processing etc). The comma in a .csv is used to separate entries, so you can’t have the comma within the entry.
No it is not more complex, simply open the original spreadsheet file and re-save as Tab Delimited Value file ensuring a .txt filename extension. The fields will be separated with tab characters, preserving the comma character within each entry/field/record.
Otherwise open the .csv into a spreadsheet program and re-save as Tab Delimited Value file ensuring a .txt filename extension… But be careful that the comma separator does not split the record into another entry, you may need to tidy this up first.
Paul Riggott originally wrote the following instructions:
N.B. The first field in the input file MUST be the filename only IE:- CRW_0001.jpg
This script will allow you to choose the fields and order they are in within either your CSV or TEXT file so that you can input your metadata.
Fields available are:-
Keywords 1 - These are Keywords that are in ONE field seperated by semicolons
Keywords 2 - These are Keywords in seperate fields. These must be last in the list/file!
N.B. Only one type of Keywords allowed!
Description - Text, if commas are in this field input file MUST be Tab Delimited!
Headline - Text, if commas are in this field input file MUST be Tab Delimited!
Title - Text, if commas are in this field input file MUST be Tab Delimited!
Instructions - Text, if commas are in this field input file MUST be Tab Delimited!
Date Created - Date IE: 12/24/2001
Location - Text, if commas are in this field input file MUST be Tab Delimited!
City - Text
Country - Text
Rating - This should be numeric 1 to 5
CopyrightInfo - Text, if commas are in this field input file MUST be Tab Delimited!
Author - Text
Label - Text, one of Select, Second, Approved, Review or To Do
There is the option to remove a header line if one exists.
Sub-Folders are supported.
Copyright all documents supported.
An error file is created and shown on completion.
Copy link to clipboard
Copied
This script seems to be working well in Bridge CC 2018 for annotating JPEGs and MP4. It is failing to annotate PDF, however.
I loked through the script and did not see anything that seemed to exclude PDF files from notation, and they are modifiable in the metadata panel in Bridge.
Anybody have insight on why this might fail?
TIA
Copy link to clipboard
Copied
I have found a solution for my issue, thanks to John Beardsworth. It turns out that there was something that was making Bridge fail to annotate just the PDFs. Making any metadata change *manually* to the PDF made the metadata writable and fixed the problem.
There is not an obvious difference to me between the PDF file type before and after the metadata change, but since the solution is so easy, I'm not investigating the issue any further at the moment. .
Copy link to clipboard
Copied
Stephen,
I have read through this entire post and this makes my head hurt :0 I need help and I hoping you or Super Merlin can give me some input.
I have multiple drone images (from drone mapping) that need to have dynamic XMP tags added to them from a CSV file. I am hoping that I can find a simple program or script so that others who do not have Bridge can use this same method.
The XMP tags that need to be added are:
Rtk Flag
Rtk Std Lon
Rtk Std Lat
Rtk Std Hgt
And actually the [Rtk Flag] tag will already exist. It will need to be updated but the other three tags have to be added along with their values. The data for these tags will be in an CSV file which will also contain the image file name.
The number of images could vary from 250 to 2000+. I have tried multiple GUI front ends for the Exiftool.exe and none of them will work like this. It seems the most typical need to update many images with the same data (ie Artist, Copyright, etc). But I need to update each image with data contained in the CSV file.
Any help on this will be appreciated. The programmer from MetaData++ said she will work on something but I have no idea on how long that will be. I would pay someone to show me the code to use in order to update photos using ExifTool.exe and just change the source CSV file path, and the Image path.
Thanks for any help!
Tim
Copy link to clipboard
Copied
The image above already contains the tags that I am needing to add.
This image does not contain the tags. So the images I need to alter will be like the image with Red Roofs.
Copy link to clipboard
Copied
The first image has the following metadata:
[XMP-drone-dji] RtkFlag : 16
[XMP-drone-dji] RtkStdLon : 1.85592
[XMP-drone-dji] RtkStdLat : 1.25373
[XMP-drone-dji] RtkStdHgt : 3.37184
While the second only has:
[XMP-drone-dji] RtkFlag : 0
So, ExifTool can read the metadata, however writing the metadata will need further investigation...
EDIT: OK, this is not a standard tag that can be written… I’ll need to look into using a custom configuration file. To be continued...
Copy link to clipboard
Copied
You would have to define a custom namespace for these tags unless DJI has a published namespace. Once you have that, Bridge can handle it with a script.
Copy link to clipboard
Copied
Hi Lumigraphics, I found this on DJI but it does not appear anything has been udpated since 2017 so new tags I am referencing are not in the list.
Copy link to clipboard
Copied
Hi Stephen. Thanks for checking on this!! That is correct. The second image is one of my own images and I need to add the tags so that the XMP section is like the first image. In my previous post I left out the fact that I need to update the GPS coordinates. So the following tags need to be updated.
These 4 tags need to be updated with data from the CSV file.
GPS Latitude
GPS Longitude
GPS Altitude
Rtk Flag (this is in the XMP section - see below)
-----------------
These three tags need to be added and contain the data from CSV file.
Rtk Std Lon
Rtk Std Lat
Rtk Std Hgt
----------------------------------------------------------------------
Here is the full XMP section that I exported out from an image that already contains ALL the tags. This image was taken with a DJI drone that writes the data out. My drone does not write the tags which is why I need to insert them. The new tags have to be in the XMP section.
---- XMP ----
About : DJI Meta Data
Modify Date : 2019:01:18
Create Date : 2019:01:18
Make : DJI
Camera Model Name : FC6310R
Format : image/jpg
Absolute Altitude : +166.15
Relative Altitude : +100.20
Gps Latitude : 52.39257959
Gps Longtitude : 12.61649563
Gimbal Roll Degree : +0.00
Gimbal Yaw Degree : +112.90
Gimbal Pitch Degree : -89.90
Flight Roll Degree : +6.30
Flight Yaw Degree : +112.30
Flight Pitch Degree : -3.60
Flight X Speed : -2.60
Flight Y Speed : +6.50
Flight Z Speed : +0.00
Cam Reverse : 0
Gimbal Reverse : 0
Self Data : Undefined
Calibrated Focal Length : 3666.666504
Calibrated Optical Center X : 2736.000000
Calibrated Optical Center Y : 1824.000000
Rtk Flag : 16
Rtk Std Lon : 1.67029
Rtk Std Lat : 1.07067
Rtk Std Hgt : 2.24660
Dewarp Data : 2018-09-08;3667.610000000000,3661.110000000000,-15.600000000000,5.370000000000,-0.268462000000,0.113513000000,-0.000452653000,-0.000422281000,-0.034791700000
Dewarp Flag : 0
Version : 7.0
Has Settings : False
Has Crop : False
Already Applied : False
Copy link to clipboard
Copied
Could you test this script on a couple of files?
The requirements are:
CSV file format:
No header line
filename,RtkFlag,RtkStdLon,RtkStdLat,RtkStdHgt
The filename must not have a path, I.E filename.jpg
You must be in the folder where the files are in Bridge.
Script...
#target bridge
if( BridgeTalk.appName == "bridge" ) {
var drone = new MenuElement( "command", "Drone Metadata", "at the end of Tools" );
}
drone.onSelect = function () {
var csvFile = File.openDialog("Open Comma-delimited File","comma-delimited(*.csv):*.csv;");
if (!csvFile.exists) return;
csvFile.open('r');
var data = csvFile.read().split("\n");
csvFile.close();
var line = new Array();
for(var a in data){
var Q = data.toString().replace(/\s+/g,'');
if(Q.length > 2) line.push(Q);
}
for(var z in line){
var p=line
.split(','); droneMetadata(p[0],p[1],p[2],p[3],p[4]);
}
function droneMetadata(th,Flag,Lon,Lat,Hgt){
var thumb = new Thumbnail(new File(new Folder(app.document.presentationPath)+ '/' + th));
md = thumb.synchronousMetadata;
if(thumb.hasMetadata){
md.namespace = "http://www.dji.com/drone-dji/1.0/";
md.RtkFlag = '';
md.RtkFlag = Flag;
md.RtkStdLon = '';
md.RtkStdLon = Lon;
md.RtkStdLat = '';
md.RtkStdLat = Lat;
md.RtkStdHgt = '';
md.RtkStdHgt = Hgt;
}else{
alert("Cannot write metadata to " + decodeURI(thumb.spec));
}
};
};
Copy link to clipboard
Copied
SuperMerlin,
I will give this a shot. I am new to Bridge and scripting but I think I can figure this out. i will let you know.
I named the script DJI_script. I just need to get my CSV file laid out for a set of photos. It might take me just a little bit as I have to leave the office but as soon as I get back I will knock this out and let you know the results.
Tim
Copy link to clipboard
Copied
Copy link to clipboard
Copied
SuperMerlin,
It freezes Bridge up. I have to open task manager and close it.
1. I open the folder where the images are located
2. I click on Tools>Drone Metadata
3. Browse to select the CSV file that is in the same folder as images themselves.
4. Click on OK and then it does nothing and it freezes.
I uploaded the batch of photos and the CSV file to Dropbox
Dropbox - XMP Tag Testing - Simplify your life
Thanks again for your help!
Copy link to clipboard
Copied
You have selected one or more images, right? The screenshot does not show this...
Copy link to clipboard
Copied
I did not the first time but it did the same thing this time when I selected them.