def write_new_date(filename: Path, new_date: datetime): logging.info('update file ' + str(filename) + ' with ' + str(new_date)) with open(filename, 'rb') as image_file: image = Image(image_file) new_date_str = new_date.strftime(DATETIME_STR_FORMAT) image.datetime_original = new_date_str image.datetime = new_date_str with open(filename, 'wb') as new_image_file: new_image_file.write(image.get_file())
def main(): # Open JSON file # Parser JSON headers = {"Content-type": "application/x-www-form-urlencoded"} fd = open("memories_history.json") memories = json.load(fd) for x in memories["Saved Media"]: if x["Media Type"] == "PHOTO": url = x["Download Link"] split_url = url.split("?") r = requests.post( split_url[0], headers=headers, data=split_url[1], ) if r.status_code == 200: # 200 means that we got HTTP success aws_resp = requests.get(r.text) aws_url = r.text.split("?") print(aws_url[0]) last_occur = aws_url[0].rfind("/", 0) + 1 print(last_occur) filename = aws_url[0][last_occur:] i = Image.open(BytesIO(aws_resp.content)) i = i.save(filename, quality="keep") time.sleep(1) # Prepare the datetime info date_datetime = datetime.strptime(x["Date"], "%Y-%m-%d %H:%M:%S %Z") with open(filename, "rb") as image_file_thing: image_file = EImage(image_file_thing) image_file.datetime_original = date_datetime.strftime( DATETIME_STR_FORMAT) image_file.datetime_scanned = date_datetime.strftime( DATETIME_STR_FORMAT) image_file.datetime_digitized = date_datetime.strftime( DATETIME_STR_FORMAT) with open("{}_akk.jpg".format(filename), "wb") as new_image_file: new_image_file.write(image_file.get_file()) else: print(r.status_code) exit() fd.close()
def change_datetimes(image_path, time_delta): """Take in image file and time change as a time delta object. Change exif datetime, datetime_digitized, and datetime_original Save file with updated exif datetimes.""" # Open image. with open(image_path, 'rb') as image_file: image = Image(image_file) # Generate new datetime. old_datetime = datetime.datetime.strptime(image.datetime, '%Y:%m:%d %H:%M:%S') new_datetime = (old_datetime + time_delta).strftime("%Y:%m:%d %H:%M:%S") # Replace all exif datetimes with new datetime. image.datetime = new_datetime image.datetime_digitized = new_datetime image.datetime_original = new_datetime # Rewrite image file. with open(image_path, 'wb') as new_image_file: new_image_file.write(image.get_file()) print(f"{image_path[7::]} datetime fixed!")
def test_add_to_scanner_image(): """Test adding metadata to a scanner-produced JPEG without any pre-existing APP1 or EXIF.""" image = Image( os.path.join(os.path.dirname(__file__), "scanner_without_app1.jpg")) assert not image.has_exif image.gps_latitude = (41.0, 29.0, 57.48) image.gps_latitude_ref = "N" image.gps_longitude = (81.0, 41.0, 39.84) image.gps_longitude_ref = "W" image.gps_altitude = 199.034 image.gps_altitude_ref = GpsAltitudeRef.ABOVE_SEA_LEVEL image.make = "Acme Scanner Company" image.model = "Scan-o-Matic 5000" image.datetime_original = "1999:12:31 23:49:12" image.datetime_digitized = "2020:07:11 10:11:37" image.brightness_value = 10.9876 # provides coverage for SRATIONAL image.user_comment = "This image was scanned in from an old photo album." # provides coverage for user comment assert image.has_exif assert image.gps_latitude == (41.0, 29.0, 57.48) assert image.gps_latitude_ref == "N" assert image.gps_longitude == (81.0, 41.0, 39.84) assert image.gps_longitude_ref == "W" assert image.gps_altitude == 199.034 assert image.gps_altitude_ref == GpsAltitudeRef.ABOVE_SEA_LEVEL assert image.make == "Acme Scanner Company" assert image.model == "Scan-o-Matic 5000" assert image.datetime_original == "1999:12:31 23:49:12" assert image.datetime_digitized == "2020:07:11 10:11:37" assert image.brightness_value == 10.9876 # provides coverage for SRATIONAL assert (image.user_comment == "This image was scanned in from an old photo album." ) # provides coverage for user comment segment_hex = (binascii.hexlify( image._segments["APP1"].get_segment_bytes()).decode("utf-8").upper()) assert "\n".join(textwrap.wrap(segment_hex, 90)) == ADD_TO_SCANNED_IMAGE_BASELINE
def strip_exifdates(myfile, date_now, dryrun): """Function to remove known EXIF date data that affects sorting""" if dryrun == False: local_exceptions = {} with open(myfile, "rb") as image_file: try: my_image = Image(image_file) except AssertionError as err: exc_type, value, traceback = sys.exc_info() local_exceptions[myfile] = exc_type logger.exception( f"exif library exception caught with {myfile}", exc_info=True) return try: logger.debug( f"Attempting to modify EXIF datetime for {myfile}") logger.debug(f"Before my_image.datetime: {my_image.datetime}") my_image.datetime = f"{date_now.year}:{date_now.month}:{date_now.day} {date_now.hour}:{date_now.minute}:{date_now.second}" logger.debug(f"After my_image.datetime: {my_image.datetime}") except (AttributeError, KeyError) as err: exc_type, value, traceback = sys.exc_info() local_exceptions[myfile] = exc_type logger.exception( f"Exception caught modifying datetime with {myfile}", exc_info=True) pass try: logger.debug( f"Attempting to modify EXIF datetime_original for {myfile}" ) logger.debug( f"Before my_image.datetime_original: {my_image.datetime_original}" ) my_image.datetime_original = f"{date_now.year}:{date_now.month}:{date_now.day} {date_now.hour}:{date_now.minute}:{date_now.second}" logger.debug( f"After my_image.datetime_original: {my_image.datetime_original}" ) except (AttributeError, KeyError) as err: exc_type, value, traceback = sys.exc_info() local_exceptions[myfile] = exc_type logger.exception( f"Exception caught modifying datetime_original with {myfile}", exc_info=True) pass try: logger.debug( f"Attempting to modify EXIF datetime_digitized for {myfile}" ) logger.debug( f"Before my_image.datetime_digitized: {my_image.datetime_digitized}" ) my_image.datetime_digitized = f"{date_now.year}:{date_now.month}:{date_now.day} {date_now.hour}:{date_now.minute}:{date_now.second}" logger.debug( f"After my_image.datetime_digitized: {my_image.datetime_digitized}" ) except (AttributeError, KeyError) as err: exc_type, value, traceback = sys.exc_info() local_exceptions[myfile] = exc_type logger.exception( f"Exception caught modifying datetime_digitized with {myfile}", exc_info=True) pass try: logger.debug( f"Attempting to modify EXIF gps_datestamp for {myfile}") logger.debug( f"Before my_image.gps_datestamp: {my_image.gps_datestamp}") my_image.gps_datestamp = f"{date_now.year}:{date_now.month}:{date_now.day}" logger.debug( f"After my_image.gps_datestamp: {my_image.gps_datestamp}") except (AttributeError, KeyError) as err: exc_type, value, traceback = sys.exc_info() local_exceptions[myfile] = exc_type logger.exception( f"Exception caught modifying gps_datestamp with {myfile}", exc_info=True) pass with open(myfile, "wb") as new_image_file: new_image_file.write(my_image.get_file()) if dryrun == True: print(f"DRYRUN: Would have removed EXIF date data on {myfile}") logger.debug(f"Iteration exceptions: {local_exceptions}") return local_exceptions
def processFile(args): argob, path = args path = Path(path) file_info = { "creation": None, "file_prefix": "", "file_suffix": "", "file_content_type": "", "old_conflict": "", "dtpattern_in_path": False, "conflict_count": 0, "cleaned_file_name": "" } creation = None image_exif = None image_exif_date_error = False lower_suffix = path.suffix.lower() if lower_suffix in img_suffixes: file_info["file_content_type"] = "IMG" try: with path.open(mode='rb') as f: image_exif = Image(f) except Exception as exc: logger.debug("Exception while reading exif: %s" % exc) if not image_exif or not image_exif.has_exif: logger.debug("image has no exif data/is not compatible: %s", path) image_exif = None elif hasattr(image_exif, "datetime"): try: creation = \ dt.strptime(image_exif.datetime, "%Y:%m:%d %H:%M:%S") except ValueError: logger.warning("Invalid format: %s", image_exif.datetime) image_exif_date_error = True elif hasattr(image_exif, "datetime_original"): try: creation = \ dt.strptime( image_exif.datetime_original, "%Y:%m:%d %H:%M:%S" ) except ValueError: logger.warning("Invalid format: %s", image_exif.datetime_original) image_exif_date_error = True elif lower_suffix in mov_suffixes: file_info["file_content_type"] = "MOV" else: if not argob.prune: logger.info("unrecognized file: %s", path) elif argob.dry_run: logger.info("Would remove: %s (unrecognized)", path) else: path.unlink() return 1 if argob.conflict == "ignore": file_info["cleaned_file_name"] = path.stem else: # find conflict counter and hash conflictmatch = extract_conflict_pattern.match(path.stem).groupdict() file_info["cleaned_file_name"] = conflictmatch["unrelated"] if conflictmatch["conflict_hash"]: if argob.conflict == "hash": # if hash is found, one conflict is indicated file_info["conflict_count"] = 1 else: file_info["cleaned_file_name"] = "%s-%s" % ( file_info["cleaned_file_name"], conflictmatch["conflict_hash"]) # if hash and counter: conflict_count = counter + 1 # if counter: conflict_count = counter # if hash: conflict_count = 1 file_info["conflict_count"] += \ int(conflictmatch["conflict_counter"] or 0) # check and potential extract datetime info from filename dtnamematch = extraction_pattern.match(file_info["cleaned_file_name"]) if dtnamematch: dtnamematchg = dtnamematch.groupdict() file_info["file_prefix"] = dtnamematchg["prefix"] or "" file_info["file_suffix"] = dtnamematchg["suffix"] or "" file_info["dtpattern_in_path"] = True if not creation: logger.debug("extract time from path: %s", path) creation = dt(year=int(dtnamematchg["year"]), month=int(dtnamematchg["month"]), day=int(dtnamematchg["day"]), hour=int(dtnamematchg["hour"] or 0), minute=int(dtnamematchg["minute"] or 0), second=int(dtnamematchg["second"] or 0)) # still no creation time if not creation: logger.debug("extract time from st_ctime: %s", path) creation = dt.fromtimestamp(path.stat().st_ctime) file_info["creation"] = creation if image_exif_date_error: file_info["old_file_hash"] = generate_hash(path) if argob.dry_run: logger.info("Would fix: %s to %s, of %s", image_exif.datetime, creation.strftime("%Y:%m:%d %H:%M:%S"), path) else: image_exif.datetime = creation.strftime("%Y:%m:%d %H:%M:%S") image_exif.datetime_original = image_exif.datetime with path.open(mode='wb') as f: f.write(image_exif.get_file()) file_info["file_hash"] = generate_hash(path) if rename_file(argob, path, file_info): return 1 return 0
args.crop_left:width - args.crop_right] cv2.imwrite("tmp.jpg", image) e_image = Image("tmp.jpg") e_image.gps_latitude = lat2 e_image.gps_latitude_ref = latref e_image.gps_longitude = lon2 e_image.gps_longitude_ref = lonref e_image.gps_img_direction = new_bear e_image.gps_dest_bearing = new_bear e_image.make = make e_image.model = model datetime_taken = datetime.fromtimestamp(new_ts + args.timezone * 3600) e_image.datetime_original = datetime_taken.strftime( DATETIME_STR_FORMAT) with open( folder + os.path.sep + input_ts_file.split( os.path.sep)[-1].replace(".ts", "_") + "_" + "%06d" % count + ".jpg", 'wb') as new_image_file: new_image_file.write(e_image.get_file()) #print('Frame: ', framecount) count += 1 else: if errormessage == 0: print( "No valid GPS for frame %d, this frame and others will be skipped." % framecount) errormessage = 1