#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. //Code to modify the "artist" exif field to store information about the experiment used to generate a graph. Requires ExifTool (https://exiftool.org/) to be installed. //Stores the path and name of the experiment, the date the file was saved, and the name and title of the graph window. //I used the artist field out of laziness and because Igor doesn't write to it. I'm sure there is a beter way. //I don't know if there is a maximum length for the artist field. I padded the info string with numbers from 0 to 99 (with spaces in between each number) //and that worked fine, so maybe not? //It seems to work on Igor 8.04 on Windows 10 and MacOS Mojave (10.14.6). The only stress testing I have done is the string length and making sure it //works with paths/names with spaces. //Code by Kyle Zarzana //Change this path for a new user, though if you install to C then you probably don't have to change anything STATIC STRCONSTANT kstrExifTool_Path_Windows="C:Windows:exiftool.exe" STATIC STRCONSTANT kstrExifTool_Path_Mac="Macintosh HD:usr:local:bin:exiftool" //Need the Macintosh HD for ParseFilePath to work properly ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MENU "Exif Tools" "Write image info", ExifTools_Menu_Write_Info() "-" "Read image info", ExifTools_Menu_Read_Info() "-" "Make panel", ExifTools_Make_Panel() END ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FUNCTION ExifTools_Make_Panel() String strExifTools_Window=UniqueName("ExifTools_Panel_", 9, 0) NewPanel/W=(382,130,1220,330)/N=$strExifTools_Window/K=1 as strExifTools_Window SetVariable SetVar_Top_Graph_Name,pos={18.00,26.00},size={374.00,19.00},bodyWidth=300,title="Graph Name:",frame=0,value= _STR:"",noedit= 1 SetVariable SetVar_Top_Graph_Title,pos={27.00,43.00},size={365.00,19.00},bodyWidth=300,title="Graph Title:",frame=0,value= _STR:"",noedit= 1 Button Button_Get_Top_Graph,pos={20.00,7.00},size={95.00,20.00},proc=ExifTools_Button_Get_Top_Graph,title="Get top graph",fColor=(3,52428,1) PopupMenu Pop_File_Type,pos={26.00,65.00},size={85.00,17.00},title="File type",mode=2,popvalue="png",value= #"\"jpg;png\"" CheckBox Check_Transparent,pos={132.00,65.00},size={74.00,16.00},title="Transparent",value= 0 PopupMenu Pop_Resolution,pos={14.00,85.00},size={120.00,17.00},title="Resolution",mode=3,popvalue="4X Screen",value= #"\"1X Screen;2X Screen;4X Screen;5X Screen;8X Screen;\"" SetVariable SetVar_File_Name,pos={13.00,128.00},size={359.00,19.00},bodyWidth=300,title="File Name:",value= _STR:"" SetVariable SetVar_Folder_Path,pos={6.00,107.00},size={766.00,19.00},bodyWidth=700,title="Folder Path:",value= _STR:"" Button Button_Folder_Path,pos={714,128.00},size={55.00,20.00},proc=ExifTools_Button_Get_Folder_Path,title="Browse",fColor=(3,52428,1) Button Button_Save_Graph,pos={34.00,152.00},size={50.00,20.00},proc=ExifTools_Button_Save_Graph,title="Save",fColor=(3,52428,1) CheckBox Check_Keep_ExifTool_Batch_File,pos={125.00,154.00},size={96.00,16.00},title="Keep batch file?",value= 0 END ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FUNCTION ExifTools_Button_Get_Top_Graph(ctrlName) : ButtonControl String ctrlName String strGraph_Window_Name=WinName(0, 1) IF(strlen(strGraph_Window_Name)>0) GetWindow/Z $strGraph_Window_Name title String strWindow_Title=S_Value SetVariable SetVar_Top_Graph_Name, value=_STR:strGraph_Window_Name SetVariable SetVar_Top_Graph_Title, value=_STR:strWindow_Title SetVariable SetVar_File_Name, value=_STR:strGraph_Window_Name ENDIF END ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FUNCTION ExifTools_Button_Get_Folder_Path(ctrlName) : ButtonControl String ctrlName String strMessage="Select a folder" NewPath/Q/O/M=strMessage pTemp_Path //Gets the path to a FOLDER (not a file) PathInfo pTemp_path SetVariable SetVar_Folder_Path, value=_STR:S_Path KillPath/Z pTemp_path END ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FUNCTION ExifTools_Button_Save_Graph(ctrlName) : ButtonControl String ctrlName ControlInfo SetVar_Top_Graph_Name String strGraph_Window_Name=S_Value IF(WinType(strGraph_Window_Name)==1) ControlInfo Pop_File_Type String strFile_Type=S_Value Variable vFile_Type=SelectNumber(cmpstr(strFile_Type, "png")==0, -6, -5) ControlInfo Check_Transparent Variable vTransparent=V_Value ControlInfo Pop_Resolution String strResolution=S_Value Variable vResolution sscanf strResolution, "%dX Screen", vResolution ControlInfo SetVar_Folder_Path String strFolder_Path=S_Value ControlInfo SetVar_File_Name String strFile_Name_No_Extension=S_Value ControlInfo Check_Keep_ExifTool_Batch_File Variable vKeep_Batch_File=V_Value String strPicture_File_Path=strFolder_Path+strFile_Name_No_Extension+"."+strFile_Type SavePICT/O/WIN=$strGraph_Window_Name/E=(vFile_Type)/B=(vResolution*72)/TRAN=(vTransparent) as strPicture_File_Path ExifTools_Write_Parameter(strGraph_Window_Name, strPicture_File_Path, vKeep_Batch_File) Print "Saved "+strGraph_Window_Name+" as "+strFolder_Path+strFile_Name_No_Extension+"."+strFile_Type ELSE DoAlert/T="PEBCAK ERROR!" 0, "Invalid graph name!" ENDIF END ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Menu function to write the info string FUNCTION ExifTools_Menu_Write_Info() Variable vRefNum Open/D/R/T="????"/M="Select a file" vRefNum IF(strlen(S_FileName)>0) String strPicture_File_Path=S_FileName Variable vKeep_Batch_File=0 //For debugging String strGraph_Window_Name=WinName(0, 1) Prompt strGraph_Window_Name, "Window name (default is top graph)" Prompt vKeep_Batch_File, "Keep batch file (for debugging)?" DoPrompt "Check window name!", strGraph_Window_Name, vKeep_Batch_File ExifTools_Write_Parameter(strGraph_Window_Name, strPicture_File_Path, vKeep_Batch_File) ENDIF END ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //ACtually calls ExifTool to write the info string to the artist field. Shared by several functions. FUNCTION ExifTools_Write_Parameter(String strGraph_Window_Name, String strPicture_File_Path, Variable vKeep_Batch_File) Variable vIs_Windows=StringMatch(IgorInfo(2), "*Win*") //Checks the OS String strPath_Separator=SelectString(vIs_Windows, "/", "\\") PathInfo home String strPXP_Path=S_Path String strPXP_Name=IgorInfo(1) String strDate=Secs2Date(DateTime, -2) String strTime=Secs2Time(DateTime, 3) String strUTC_Offset=num2str(floor(Date2Secs(-1,-1,-1)/3600)) GetWindow/Z $strGraph_Window_Name title String strGraph_Window_Title=S_Value String strInfo_String="Experiment="+strPXP_Path+strPXP_Name+".pxp;Save date="+strDate+" "+strTime+" (UTC"+strUTC_Offset+");Window name="+strGraph_Window_Name+";Window title="+strGraph_Window_Title+";" String strGraph_File_Path_Formatted=ParseFilePath(5, strPicture_File_Path, strPath_Separator, 0, 0) String strExifTool_exe_Path_Formatted=ParseFilePath(5, SelectString(vIs_Windows, kstrExifTool_Path_Mac, kstrExifTool_Path_Windows), strPath_Separator, 0, 0) IF(vIs_Windows) IF(StringMatch(strGraph_File_Path_Formatted, "* *")) strGraph_File_Path_Formatted="\""+strGraph_File_Path_Formatted+"\"" ENDIF String strBat_File_Text=strExifTool_exe_Path_Formatted+" -overwrite_original_in_place -artist="+"\""+strInfo_String+"\" "+strGraph_File_Path_Formatted String strBat_File_Name="Exif_Batch_"+ReplaceString("-", strDate, "")+"_"+ReplaceString(":", strTime, "")+".bat" //Use the date and time to give the batch file a unique name String strBat_File_Path_Formatted=ParseFilePath(5, strPXP_Path+strBat_File_Name, "\\", 0, 0) Variable vFileID_Batch Open vFileID_Batch as strPXP_Path+ strBat_File_Name //Cretes the batch file, use the date and time to make it unique fprintf vFileID_Batch, strBat_File_Text //Write the new string to the batch file Close vFileID_Batch IF(StringMatch(strBat_File_Path_Formatted, "* *")) strBat_File_Path_Formatted="\""+strBat_File_Path_Formatted+"\"" ENDIF ExecuteScriptText strBat_File_Path_Formatted IF(!vKeep_Batch_File) DeleteFile/Z strPXP_Path+ strBat_File_Name ENDIF ELSE //Mac code IF(StringMatch(strGraph_File_Path_Formatted, "* *")) strGraph_File_Path_Formatted="'"+strGraph_File_Path_Formatted+"'" ENDIF strInfo_String="'"+strInfo_String+"'" String strScript_Command="do shell script \""+strExifTool_exe_Path_Formatted+" -overwrite_original_in_place -artist="+strInfo_String+" "+strGraph_File_Path_Formatted+"\"" ExecuteScriptText strScript_Command ENDIF END ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Reads and parses the artist field using ExifTool FUNCTION ExifTools_Menu_Read_Info() Variable vKeep_Batch_File=0 //For debugging if needed Variable vKeep_Info_File=0 //For debugging if needed Variable vRefNum Open/D/R/T="????"/M="Select a file" vRefNum IF(strlen(S_FileName)>0) String strPicture_File_Path=S_FileName Variable vIs_Windows=StringMatch(IgorInfo(2), "*Win*") //Checks the OS String strPath_Separator=SelectString(vIs_Windows, "/", "\\") String strPicture_Folder_Path=ParseFilePath(1, strPicture_File_Path, ":", 1, 0) String strPicture_File_Path_Formatted=ParseFilePath(5, strPicture_File_Path, strPath_Separator, 0, 0) String strDate=Secs2Date(DateTime, -2) //Use the date and time to give the batch and info file unique names String strTime=Secs2Time(DateTime, 3) String strOutput_File_Name="Exif_Info_"+ReplaceString("-", strDate, "")+"_"+ReplaceString(":", strTime, "")+".txt" String strOutput_File_Path_Formatted=ParseFilePath(5, strPicture_Folder_Path, strPath_Separator, 0, 0)+strOutput_File_Name //Since the output file doesn't exist yet, I apparently have to add the file name outside ParseFilePath String strExifTool_exe_Path_Formatted=ParseFilePath(5, SelectString(vIs_Windows, kstrExifTool_Path_Mac, kstrExifTool_Path_Windows), strPath_Separator, 0, 0) IF(vIs_Windows) IF(StringMatch(strPicture_File_Path_Formatted, "* *")) strPicture_File_Path_Formatted="\""+strPicture_File_Path_Formatted+"\"" ENDIF IF(StringMatch(strOutput_File_Path_Formatted, "* *")) strOutput_File_Path_Formatted="\""+strOutput_File_Path_Formatted+"\"" ENDIF String strBat_File_Name="Exif_Batch_"+ReplaceString("-", strDate, "")+"_"+ReplaceString(":", strTime, "")+".bat" String strBat_File_Path_Formatted=ParseFilePath(5, strPicture_Folder_Path+strBat_File_Name, strPath_Separator, 0, 0) String strBat_File_Text=strExifTool_exe_Path_Formatted+" -artist "+strPicture_File_Path_Formatted+" >"+strOutput_File_Path_Formatted Variable vFileID_Batch Open vFileID_Batch as strPicture_Folder_Path+strBat_File_Name //Cretes the batch file, use the date and time to make it unique fprintf vFileID_Batch, strBat_File_Text //Write the new string to the batch file Close vFileID_Batch IF(StringMatch(strBat_File_Path_Formatted, "* *")) strBat_File_Path_Formatted="\""+strBat_File_Path_Formatted+"\"" ENDIF ExecuteScriptText strBat_File_Path_Formatted ELSE IF(StringMatch(strPicture_File_Path_Formatted, "* *")) strPicture_File_Path_Formatted="'"+strPicture_File_Path_Formatted+"'" ENDIF IF(StringMatch(strOutput_File_Path_Formatted, "* *")) strOutput_File_Path_Formatted="'"+strOutput_File_Path_Formatted+"'" ENDIF String strScript_Command="do shell script \""+strExifTool_exe_Path_Formatted+" -artist "+strPicture_File_Path_Formatted+" >"+strOutput_File_Path_Formatted+"\"" ExecuteScriptText strScript_Command ENDIF //End checking the OS GetFileFolderInfo/Q/Z strPicture_Folder_Path+strOutput_File_Name IF(V_Flag==0 && V_IsFile) String strOutput_Line Variable vFileID_Output Open/R vFileID_Output as strPicture_Folder_Path+strOutput_File_Name FReadLine vFileID_Output, strOutput_Line Close vFileID_Output Variable vStart=strsearch(strOutput_Line, "Experiment", 0, 2) String strInfo_String=strOutput_Line[vStart, strlen(strOutput_Line)-1] String strPXP_Path=StringbyKey("Experiment", strInfo_String, "=", ";") String strSave_Date=StringbyKey("Save date", strInfo_String, "=", ";") String strWindow_Name=StringbyKey("Window name", strInfo_String, "=", ";") String strWindow_Title=StringbyKey("Window Title", strInfo_String, "=", ";") Print "Picture file: "+strPicture_File_Path Print "Experiment: "+strPXP_Path Print "Save date: "+strSave_Date Print "Window name: "+strWindow_Name Print "Window title: "+strWindow_Title IF(!vKeep_Info_File) DeleteFile/Z strPicture_Folder_Path+strOutput_File_Name ENDIF ENDIF //End making sure the info file exists IF(vIs_Windows && !vKeep_Batch_File) DeleteFile/Z strPicture_Folder_Path+strBat_File_Name ENDIF ENDIF //End making sure the picture file exists END ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////