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()
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)
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?)
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.
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)
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")
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