Convert blob/image to Python Image

447
4
05-14-2024 07:04 AM
KåreMølgaardRasmussen
New Contributor

Hi Community.

I´m currently working on a script that is able to send an email thru (arc)PY. 

I´m using a searhcursor to find the relavant data including blob-data from the _ATTACH table.

But I´m missing a way to convert the blob data to an image (via the PIL framework)

I´ve tried something like this:

with arcpy.da.SearchCursor(_fcAttach,fieldsIn) as imageCursor:
for row in imageCursor:
tmpImg = row[1] #the 'DATA'-field
                binary_data = base64.b64decode(tmpImg)
                ioData = io.BytesIO(binary_data)
                image = Image.open(ioData)
But I get an error like:
PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x0000011D99E7BE50>
Any suggestions or ideas?

Regards

Kåre

0 Kudos
4 Replies
BlakeTerhune
MVP Regular Contributor

Sorry, I have not worked with images much, but you could try ImageMagick or wand.

0 Kudos
JakeSkinner
Esri Esteemed Contributor

Hi @KåreMølgaardRasmussen,

The below sample will export the attachments to a directory:

import os, arcpy

# Variables
tbl = r"C:\Temp\Python\Test.gdb\Graffiti__ATTACH"       # Path to attachment table
fldBLOB = 'DATA'                                        # Field name of Blob data type field in attachment table
fldAttName = 'ATT_NAME'                                 # Field name in attachment table that contains attachment name
outFolder = r"C:\Temp\Python\Attachments"               # Output folder to export attachments to

with arcpy.da.SearchCursor(tbl,[fldBLOB,fldAttName]) as cursor:
   for row in cursor:
      binaryRep = row[0]
      fileName = row[1]
      # save to disk
      open(outFolder + os.sep + fileName, 'wb').write(binaryRep.tobytes())

print('Finished')
0 Kudos
BlakeTerhune
MVP Regular Contributor

I just noticed the ExportAttachments() function in 3.3. Maybe you could try that too if you're able to upgrade Pro.

DavidSolari
Occasional Contributor III

Last time I checked, the Data Access Cursor types return BLOB columns as memoryview objects. The docs for PIL's Image.open function say it can open any file-like object that holds binary data. If you're lucky you can just shove the memoryview in there, if not you can do something like:

 

from io import BytesIO
from PIL import Image

with arcpy.da.SearchCursor(data, fields) as cur:
    for row in cur:
        data = row[index]
        photo = Image.open(BytesIO(data))

 

I think the issue with the code above is you're decoding the binary data to base64 which is tripping up PIL, assuming your images were added to an attachment table through the standard ArcGIS methods the data is stored byte for byte without any special encoding.

0 Kudos