Export pop-up info with attachment from geodatabase

01-23-2019 03:17 PM
New Contributor III

Hello. We have been provided a geodatabase containing a point feature class and related attachments and tables. I have successfully exported the attached images from the geodatabase with the specified naming scheme. However, the question came up about whether it is possible to export attachments from the geodatabase, but this time INCLUDE the pop-up info (i.e., attribute data) in the "properties" of the image file. As an example, say an image of manhole 1_WW currently shows the xy location of the point, but it does not include any of the information that was added to the point feature class such as type, diameter, depth, etc, all of which are in the attribute table of the point.

I appreciate your help. Thank you.

Here is the script I used:

import arcpy
from arcpy import da
import os

inTable = arcpy.GetParameterAsText(0)
fileLocation = arcpy.GetParameterAsText(1)

with da.SearchCursor(inTable, ['DATA', 'ATT_NAME', 'REL_GLOBALID']) as cursor:
    for item in cursor:
        attachment = item[0]
        filenum = "ATT" + str(item[2]) + "_"
        filename = filenum + str(item[1])
        open(fileLocation + os.sep + filename, 'wb').write(attachment.tobytes())

0 Kudos
5 Replies
MVP Regular Contributor

When you say 'in the "properties" of the image file', do you mean something like saving data in the exif of a jpg, or saving a text file that would have the same name as the image file?

An old thread Query a related table and export it with joined feature attributes? might give you some ideas if you want to write data to a similarly named text file.

0 Kudos
New Contributor

Hi Crystal,

That's exactly the sort of issue I am looking into.  Have you had any luck yet?


0 Kudos
New Contributor III

Hello Randy. Thank you for the response. I am looking to save the attribute data to the exif of the jpeg. I understand that information stored with the image and in the exif is drone collected, but would like to be able to use the related feature class attributes to write in field collected point data to the exif. My test file is a one-to-one relate; but others are one-to-many. I have joined the feature class to the Attachment table but am unable to get beyond this point because you can't export the attach table to a new one and maintain the attachments. I appreciate your help. 

I hope that makes sense...I feel like I am making circular statements... 

0 Kudos
MVP Regular Contributor

The additional explanation helps - one feature to one or more photos. I've dabbled a little with exif data.  My August 24/25 comments in this thread might be of help.

You could read the feature attributes into a dictionary using the globalID as the key with a search cursor.  Then work through your related table to get the attached photos with the related globalID to access the dictionary's saved attributes.  Then save the image with new exif data.

UPDATE:  Here's some sample code that links the parent data with the related image data:

import arcpy, os

masterFC = r'C:\Path\to\file.gdb\feature'
masterFlds = [ 'GlobalID', 'SHAPE@XY', 'OBJECTID', 'Field1', 'Field2' ] # [ 'GlobalID', and fields you want... ]

relatedTbl = r'C:\Path\to\file.gdb\feature'__ATTACH'

# Use list comprehension to build a dictionary from a da SearchCursor
masterDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(masterFC, masterFlds)}
# print masterDict
# looks something like { '{6656FDEC-6BD8CF4E16AF}': ((-14962237.7272, 8031520.472999997), 421, 'attribute', ... ), ... }

sr = arcpy.Describe(masterFC).spatialReference # get spatial reference of parent feature, if desired
print sr.factoryCode

with arcpy.da.SearchCursor(relatedTbl, relatedFlds) as cursor:
    for item in cursor:
        # item[3] is Content Type
        if item[3] == 'image/jpeg': # process only images; where clause can also be used to limit results

            # item[0] is related GlobalID; use it as key to masterDict and access tuple with indexing
            x,y = masterDict[item[0]][0] # use [0] to access SHAPE@XY
            print x, y
            # get Longitude/Latitude
            ptGeometry = arcpy.PointGeometry(arcpy.Point(x,y),arcpy.SpatialReference(sr.factoryCode)).projectAs(arcpy.SpatialReference(4326))
            lon, lat = ptGeometry.firstPoint.X, ptGeometry.firstPoint.Y  

            parentOID = masterDict[item[0]][1] # use [1] to access parent ObjectID
            attribute1 = masterDict[item[0]][2] # use [2], [3], etc. to access parent feature's attributes
            attribute2 = masterDict[item[0]][3] # use [2], [3], etc. to access parent feature's attributes

            attID = item[1] # this is the Attachment ID in related table
            # make new filename for image

            filename = "ATT_{}_{}.jpg".format(parentOID, attID)
            print filename
            print lon, lat, parentOID, attribute1, attribute2
            # do your exif stuff here
            # save the image to the desired location
            # saveName = os.path.join(saveLocation, fileName)
            # f = open(saveName, 'wb').write(item[2].tobytes())

del  cursor
del item

Code still needs the exif stuff.  Hope this helps.

0 Kudos
MVP Regular Contributor

It looks like you have the image extraction down using How To: Batch export attachments from a feature class in ArcMap

  1. You need to modify your cursor to include the other attribute data you would like to include in the image metadata
  2. You then need to write this information as metadata to each image file using an additional Python module such as piexif · PyPI  or py3exiv2 · PyPI depending which version of Python you are running.  There are only a limited number of valid EXIF tags so you may need to concatenate the data into a JASON string and save it to the UserComment tag.

Example of using pyexif to write JASON data: Writing complex custom metadata on images through python - Stack Overflow