Select to view content in your preferred language

Resize Photos by 50% script erases key geotag metadata

778
6
07-06-2023 07:36 AM
AFackler_NAPSG
Occasional Contributor

I am working on a python script that will later be used as a tool in ArcGIS Pro that will take the photos from a drone, resize them by 50%, then run a geotag-to-point process. Right now, the script is set to copy all the photos into a new folder called "images_resized" as a way to indicate that these are the photos to be used and uploaded while the raw unchanged photos stay in the root folder. The issue I am running into is that when I run the resize part of the script, I end up losing the key location data I need for the script to run properly.

import os
import arcpy
from sys import argv
from datetime import date
from pathlib import Path
from PIL import Image
import shutil
source_folder_path = r"C:\Users\admin\Desktop\UASPhotos"
# Specify the destination folder path
destination_folder_path = r"{}\images_resized".format(source_folder_path)
# Create the destination folder if it doesn't exist
if not os.path.exists(destination_folder_path):
    os.makedirs(destination_folder_path)
# Get a list of all files in the source folder
file_list = os.listdir(source_folder_path)
# Loop through each file in the source folder
for file_name in file_list:
    # Create the source and destination paths
    source_path = os.path.join(source_folder_path, file_name)
    destination_path = os.path.join(destination_folder_path, file_name)

    # Check if the file is an image (you can add more file extensions if needed)
    if file_name.lower().endswith((".jpg", ".jpeg", ".png", ".bmp", ".gif")):
        # Copy the file to the destination folder
        shutil.copyfile(source_path, destination_path)

        # Open the image file from the destination folder
        with Image.open(destination_path) as image:
            # Calculate the new width and height
            new_width = int(image.width * 0.5)
            new_height = int(image.height * 0.5)

            # Resize the image
            resized_image = image.resize((new_width, new_height))

I know it's during the resize because I tried just the copy and the photos still had the info, but as soon as I run the resizer the data is gone. Any ideas on how to preserve the essential metadata or any workaround?

Edit: I also found and tried out some EXIF scripts basically running the code below but still the same result(replace after line 16 in the script above with this)

   for file_name in files:
    # Get the full path of the source file
    source_file = os.path.join(source_folder, file_name)

    # Check if the file is an image
    if not os.path.isfile(source_file) or not file_name.lower().endswith(('.jpg', '.jpeg', '.png')):
        continue

    # Open the image using PIL
    image = Image.open(source_file)

    # Resize the image
    width, height = image.size
    new_width = int(width * resize_percentage)
    new_height = int(height * resize_percentage)
    resized_image = image.resize((new_width, new_height), Image.ANTIALIAS)

    # Preserve the geotag information
    exif_data = image.info.get("exif")
    resized_image.info["exif"] = exif_data


    # Save the resized image to the destination folder
    destination_file = os.path.join(destination_folder, file_name)
    resized_image.save(destination_file)

    # Close the image
    image.close()
    resized_image.close()

 

Tags (3)
0 Kudos
6 Replies
AlfredBaldenweck
MVP Regular Contributor

I think it's because you're just closing the image, not saving it.

Basically, on line 25, add in the exif tags in the second parameter. 

(This is from code I muddled through two years ago, so it may take some more muddling on your end, but it does work for me just fine; I was able to plot each edited photo on a map no issue)

img = Image.open(output)
img = ImageOps.exif_transpose(img)

#exifdata= img.getexif() # Get general tags.

#Save the output, including the exif tags where possible.
try:
    img.save(output, exif= img.info['exif'])
except:
    img.save(output)
0 Kudos
AFackler_NAPSG
Occasional Contributor

Would you be able to explain a bit more about which lines from your script to put where? I think I put it in wrong since my images came back corrupted (I think?) 

AFackler_NAPSG_0-1688656373912.png

 

0 Kudos
AlfredBaldenweck
MVP Regular Contributor

Yikes! Sorry

Try just replacing line 25 of your second script example with image.save(destination_file, exif_data)

 

To go over what I had posted:

first line establishes the image object, the second line flips it so it's facing up correctly, then lines 7-9 save the image with the exif info from the original image (if there is any), or else saves without it if there isn't any.

0 Kudos
AFackler_NAPSG
Occasional Contributor

Alright had to retrofit a bit by adding "exif_data=exif_data", otherwise it would fail. However, the XY data still isn't being preserved. See script below (also modified to work outside of a function, so there may be a few small differences from the original above)

for file_name in file_list:
    # Get the full path of the source file
    source_file = os.path.join(source_folder_path, file_name)
    # Check if the file is an image
    if not os.path.isfile(source_file) or not file_name.lower().endswith(('.jpg', '.jpeg', '.png')):
        continue
    # Open the image using PIL
    image = Image.open(source_file)
    # image = source_file.exif_transpose(image)
    # Resize the image
    width, height = image.size
    new_width = int(width * 0.5)
    new_height = int(height * 0.5)
    resized_image = image.resize((new_width, new_height))
    # Preserve the geotag information
    exif_data = image.info.get("exif")
    resized_image.info["exif"] = exif_data
    # Save the resized image to the destination folder
    destination_file = os.path.join(destination_folder_path, file_name)
    resized_image.save(destination_file,exif_data=exif_data)
0 Kudos
AlfredBaldenweck
MVP Regular Contributor

I think the issue was on your line 20, you put "exif_data" as the parameter, instead of "exif". I changed that and it worked for me. 

Full code I used below

from PIL import Image, ImageDraw, ImageFont, ImageOps
from PIL.ExifTags import TAGS, GPSTAGS
import os

file_list = [r"Example_Photo 1.jpg"]
source_folder_path = r"W:\Downloads\deletelater\ResizeTest"
destination_folder_path = r"W:\Downloads\deletelater\ResizeTest\quaratine"

for file_name in file_list:
    # Get the full path of the source file
    source_file = os.path.join(source_folder_path, file_name)
    # Check if the file is an image
    if not os.path.isfile(source_file) or not file_name.lower().endswith(('.jpg', '.jpeg', '.png')):
        continue
    # Open the image using PIL
    image = Image.open(source_file)
    # Resize the image
    width, height = image.size
    new_width = int(width * 0.5)
    new_height = int(height * 0.5)
    resized_image = image.resize((new_width, new_height))
    # Preserve the geotag information
    exif_data = image.info["exif"]
    # Save the resized image to the destination folder
    file_nameR = file_name.split(".")[0] +"_Resized." + file_name.split(".")[1]
    destination_file = os.path.join(destination_folder_path, file_nameR)
    resized_image.save(destination_file,exif=exif_data)

print("Done")
0 Kudos
AFackler_NAPSG
Occasional Contributor

Still no bueno, images coming back corrupted or not functional like my reply a few hours back. And XY data still isn't coming over when I look at the properties

0 Kudos