Files

109 lines
4.3 KiB
Python

import os
import datetime
import numpy as np
from PIL import Image
import folder_paths
def convert_to_degrees(value):
"""Helper function to convert GPS coordinates to degrees/minutes/seconds for EXIF"""
d = int(value)
m = int((value - d) * 60)
s = (value - d - (m / 60.0)) * 3600.0
# Exif rational representation: (numerator, denominator)
return ((d, 1), (m, 1), (int(s * 1000000), 1000000))
class SaveImageWithFakeEXIF:
def __init__(self):
self.output_dir = folder_paths.get_output_directory()
self.type = "output"
self.prefix_append = ""
@classmethod
def INPUT_TYPES(s):
return {"required":
{"images": ("IMAGE", ),
"filename_prefix": ("STRING", {"default": "IMG"}),
"format": (["jpg", "png"], {"default": "jpg"}),
"camera_make": ("STRING", {"default": "Apple"}),
"camera_model": ("STRING", {"default": "iPhone 16 Pro Max"}),
"latitude": ("FLOAT", {"default": 48.8566, "min": -90.0, "max": 90.0, "step": 0.0001}),
"longitude": ("FLOAT", {"default": 2.3522, "min": -180.0, "max": 180.0, "step": 0.0001}),
}
}
RETURN_TYPES = ()
FUNCTION = "save_images"
OUTPUT_NODE = True
CATEGORY = "image"
def save_images(self, images, filename_prefix="IMG", format="jpg", camera_make="Apple", camera_model="iPhone 16 Pro Max", latitude=48.8566, longitude=2.3522):
import piexif
filename_prefix += self.prefix_append
full_output_folder, filename, counter, subfolder, filename_prefix = folder_paths.get_save_image_path(filename_prefix, self.output_dir, images[0].shape[1], images[0].shape[0])
results = list()
for batch_number, image in enumerate(images):
i = 255. * image.cpu().numpy()
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
# Create EXIF data
exif_dict = {"0th": {}, "Exif": {}, "GPS": {}, "1st": {}, "thumbnail": None}
# Make & Model
exif_dict["0th"][piexif.ImageIFD.Make] = camera_make.encode('utf-8')
exif_dict["0th"][piexif.ImageIFD.Model] = camera_model.encode('utf-8')
# Date Time (Fully Automatic)
dt = datetime.datetime.now()
dt_formatted = dt.strftime("%Y:%m:%d %H:%M:%S")
exif_dict["0th"][piexif.ImageIFD.DateTime] = dt_formatted.encode('utf-8')
exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal] = dt_formatted.encode('utf-8')
exif_dict["Exif"][piexif.ExifIFD.DateTimeDigitized] = dt_formatted.encode('utf-8')
# GPS
gps_lat = convert_to_degrees(abs(latitude))
gps_lat_ref = b'N' if latitude >= 0 else b'S'
gps_lon = convert_to_degrees(abs(longitude))
gps_lon_ref = b'E' if longitude >= 0 else b'W'
exif_dict["GPS"][piexif.GPSIFD.GPSLatitudeRef] = gps_lat_ref
exif_dict["GPS"][piexif.GPSIFD.GPSLatitude] = gps_lat
exif_dict["GPS"][piexif.GPSIFD.GPSLongitudeRef] = gps_lon_ref
exif_dict["GPS"][piexif.GPSIFD.GPSLongitude] = gps_lon
# Optional: Add realistic software version to look authentic
exif_dict["0th"][piexif.ImageIFD.Software] = b"17.4.1"
exif_bytes = piexif.dump(exif_dict)
# Construction du nom de fichier avec Date et Heure
dt_filename = dt.strftime("%Y%m%d_%H%M%S")
file = f"{filename}_{dt_filename}_{counter:05}.{format}"
output_file_path = os.path.join(full_output_folder, file)
save_format = format.upper()
if save_format == "JPG":
save_format = "JPEG"
img.save(output_file_path, format=save_format, exif=exif_bytes)
results.append({
"filename": file,
"subfolder": subfolder,
"type": self.type
})
counter += 1
return { "ui": { "images": results } }
NODE_CLASS_MAPPINGS = {
"SaveImageWithFakeEXIF": SaveImageWithFakeEXIF
}
NODE_DISPLAY_NAME_MAPPINGS = {
"SaveImageWithFakeEXIF": "Save Image (Fake EXIF)"
}