data driven image naming

12-30-2019 01:12 PM
New Contributor

I have a pretty basic survey where the person goes to park 'ABCD' location '123' and takes four photos.  Is there a way to use the Park ID and Location ID fields to name the photo.  For example: 





What I am getting now is a filename such as ATT1_LocatorImage1-20191220-175037.jpg which isn't going to be of much use to me.  From my preliminary search of older user questions, this has been a requested feature for several years.  Is it available now?  Is there a way to cross reference tabular data to the file name at least?

6 Replies
Esri Regular Contributor

Hi Michael,

We have an existing enhacement request for this:

ENH-000119299 Allow Survey123 for ArcGIS to rename the name of the collected photos based on an answer of a question or using calculation automatically instead of manually changing the name of the photos while uploading.

There is no timeframe yet for implementing this enhancement request.

I encourage you to contact Esri Support and our Support team will assign an official enhancement number for your records. Similar requests from other customers can then be attached to the same enhancement request, which helps us assess demand for the enhancement and prioritize it accordingly.


0 Kudos
New Contributor II

Dear Shwu-jingJeng

I was wondering if there have been any updates to the this initial request to create a the followign enhancement.

ENH-000119299 Allow Survey123 for ArcGIS to rename the name of the collected photos based on an answer of a question or using calculation automatically instead of manually changing the name of the photos while uploading.

I do not have the python script abilities and hoped that there would be a simple format for allocating site names to images so that they can be collated appropriately.

Any help would be greatly appreciated.

Best regards Jamie


0 Kudos
MVP Notable Contributor

You can rename them all using a calculated field from the form when exporting in a Python script.  Not sure if that will help you but I have the code for it. 

What I do now is just export them to a directory with the Plot name.  Then we have a URL or UNC path name in the feature class attributes instead.  Keeping them all in the GDB or SDE got too big rather quickly.

I guess you could export, rename and reimport but not much fun.

0 Kudos
Occasional Contributor II


If there's a script you would be willing to share for how to rename images from form fields, I would be interested in seeing how to do that. I am still running a manual process.


I collect a point for each survey but I assume this same logic can be applied to tabular survey results. I join my gdb point layer field "GLOBALID" to gbd ATTACH table field "REL_GLOBALID" . This gives me a record for each picture along with all of my survey attributes. I export that out to a csv file and use a program called Advanced Renamer to batch rename the jpg files using those added survey fields. Renamer matches the jpg file to a csv field, "Name" below, and renames the file using another field "New_Name".

Joined arcmap fields and original jpg exports from survey gdb

csv file with original jpg file names and new naming convention fields

0 Kudos
New Contributor

Thanks for the suggested workaround.  I'll give it a shot soon.

0 Kudos
MVP Notable Contributor

Sure here you go.  It does 1,700 files in 376 folders in less than 5 minutes.  Note mine is a little more complicated since I need to do some joins to get some info.  I also create the dir storage structure on the fly.

The main part is just to 

Pull out the attachment

with arcpy.da.SearchCursor("attachView", fieldList) as cursor:
      for row in cursor:
            binaryRep = row[0]

Then save it out with a diff name
open(baseOut + os.sep + fileName, 'wb').write(binaryRep.tobytes())

Hope that helps.

# Name:        Survey123 Export Photos to File System

import os, arcpy

# vars--------------------
inDB = r"\\path\Exported.gdb"
# to get the names and PrimaryKey (I have 9 forms in my GDB)
photoForm = "Photos"
# actual attachements table
attachName = "Photos__ATTACH"

outDir = r"\\yourpath\Photos"

# should be standard
fldBLOB = 'DATA'
fldAttName = 'ATT_NAME'

dateLoadedInDb = "2019-09-01"

# vars--------------------

# join to Photos form to get the PrimaryKey and state info
# Note the first year they called it PlotKey instead
arcpy.MakeTableView_management(inDB + "\\" + attachName, "attachView")
arcpy.AddJoin_management("attachView", "REL_GLOBALID", inDB + "\\" + photoForm, "globalid")
# funky due to the join
fieldList = [attachName + "." + fldBLOB, attachName + "." + fldAttName, photoForm + ".PlotKey", photoForm + ".Office", photoForm + ".filename_T1", photoForm + ".filename_T2", photoForm + ".filename_T3" \
            ,photoForm + ".filename_Soil", photoForm + ".MiscPhoto1filename", photoForm + ".MiscPhoto2filename", photoForm + ".MiscPhoto3filename", photoForm + ".MiscPhoto4filename", photoForm + ".MiscPhoto5filename"]
with arcpy.da.SearchCursor("attachView", fieldList) as cursor:
   for row in cursor:
      binaryRep = row[0]

      # save to disk
      # build output path of base + State + PrimaryKey (PlotKey + DateLoadedInDb)
      # for now need to check for blank PlotKey and blank Office - which should be fixed already
      if row[3] == None or row[2] == None:
        print "Warning Null values found in the Office or PlotKey field.  Skipping photo.  Must fix!!"
        print "   ATT_NAME is " + row[1]
        baseOut = outDir + "\\" + row[3][:2] + "\\" + row[2] + dateLoadedInDb
        # check to see if already PrimaryKey dir there - if not create it
        if not os.path.exists(baseOut):

        # Need to get the actual file name from the right field.  No real other way to do it with a SC so had to write it out
        whichPhoto = row[1].split("-")[0]
        if whichPhoto == "T1":
            fileName = row[4] + ".jpg"
        elif whichPhoto == "T2":
            fileName = row[5] + ".jpg"
        elif whichPhoto == "T3":
            fileName = row[6] + ".jpg"
        elif whichPhoto == "Soil":
            fileName = row[7] + ".jpg"
        elif whichPhoto == "MiscPhoto1":
            fileName = row[8] + ".jpg"
        elif whichPhoto == "MiscPhoto2":
            fileName = row[9] + ".jpg"
        elif whichPhoto == "MiscPhoto3":
            fileName = row[10] + ".jpg"
        elif whichPhoto == "MiscPhoto4":
            fileName = row[11] + ".jpg"
        elif whichPhoto == "MiscPhoto5":
            fileName = row[12] + ".jpg"

        # in case some / got in there.  this should not happen now!
        fileName = fileName.replace("/","")

        # save out the file
        open(baseOut + os.sep + fileName, 'wb').write(binaryRep.tobytes())

del cursor‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos