def shift_time(hours: int = 0, minutes: int = 0, seconds: int = 0, is_video: bool = False): """ shift DateTimeOriginal to correct for wrong camera time setting :example: to adjust time zone by one, set hours=-1 :param hours: hours to shift :param minutes: minutes to shift :param seconds: seconds to shift :param is_video: whether to modify videos, if false modifies pictures """ log_function_call(shift_time.__name__, hours, minutes, seconds, is_video) inpath = os.getcwd() delta_t = dt.timedelta(hours=hours, minutes=minutes, seconds=seconds) Tagdict = read_exiftags(inpath, settings.video_types if is_video else settings.image_types) if has_not_keys(Tagdict, keys=["Directory", "File Name", "Date/Time Original"]): return leng = len(list(Tagdict.values())[0]) time_tags = ["DateTimeOriginal", "CreateDate", "ModifyDate"] time_tags_mp4 = ["TrackCreateDate", "TrackModifyDate", "MediaCreateDate", "MediaModifyDate"] dir_change_printer = DirChangePrinter(Tagdict["Directory"][0]) for i in range(leng): model = create_model(Tagdict, i) time = giveDatetime(model.get_date()) newtime = time + delta_t timestring = dateformating(newtime, "YYYY:MM:DD HH:mm:ss") outTagDict = {} for time_tag in time_tags: outTagDict[time_tag] = timestring if is_video: for time_tag in time_tags_mp4: outTagDict[time_tag] = timestring write_exiftag(outTagDict, model.dir, model.filename) dir_change_printer.update(model.dir) dir_change_printer.finish()
def _detect_3D(): """ not yet fully implemented """ inpath = os.getcwd() Tagdict = read_exiftags(inpath) if has_not_keys(Tagdict, keys=[ "Directory", "File Name", "Date/Time Original", "Burst Mode", "Sequence Number" ]): return time_old = giveDatetime() filenames = [] dir3D = "3D" for i in range(len(list(Tagdict.values())[0])): newDir = os.path.join(Tagdict["Directory"][i], dir3D) os.makedirs(newDir, exist_ok=True) model = create_model(Tagdict, i) SequenceNumber = model.get_sequence_number() if model.is_series() or SequenceNumber > 1: continue time = giveDatetime(model.get_date()) timedelta = time - time_old timedelta_sec = timedelta.days * 3600 * 24 + timedelta.seconds time_old = time if timedelta_sec < 10 or (SequenceNumber == 1 and timedelta_sec < 15) or filenames == []: filenames.append(getPath(Tagdict, i)) elif len(filenames) > 1: for filename in filenames: if os.path.isfile( filename.replace(Tagdict["Directory"][i], newDir)): continue shutil.copy2(filename, newDir) filenames = []
def rename_from_exif(): """ use exif information written by :func:`write_exif_using_csv` to restore filename """ Tagdict = read_exiftags() if has_not_keys(Tagdict, keys=["Label"]): return temppostfix = renameTemp(Tagdict["Directory"], Tagdict["File Name"]) leng = len(list(Tagdict.values())[0]) for i in range(leng): filename = Tagdict["File Name"][i] ext = filename[filename.rfind('.'):] renameInPlace(Tagdict["Directory"][i], filename + temppostfix, Tagdict["Label"][i] + ext)
def rotate(subname: str = "", folder: str = r"", sign=1, override=True, ask=True): """ rotate back according to tag information (Rotate 90 CW or Rotate 270 CW) Some programs like franzis hdr projects rotate the resolution of the picture -> picture gets upward resolution and shown as rotated two times. This function reverses the resolution rotation according to exif info. Pictures that either have no rotation according to exif or have a normal resolution ratio are not modified. So calling it a second time wont change anything. :param subname: only files that contain this name are rotated, empty string: no restriction :param sign: direction of rotation :param folder: only files in directories that match this regex are rotated, empty string: no restriction :param override: override file with rotated one :param ask: if should ask for user confirmation """ log_function_call(rotate.__name__, subname, folder, sign, override, ask) from PIL import Image NFiles = 0 clock = Clock() inpath = os.getcwd() for (dirpath, dirnames, filenames) in os.walk(inpath): if is_invalid_path(dirpath, regex=folder): continue if len(filenames) == 0: continue Tagdict = read_exiftags(dirpath, settings.image_types, ask=ask) if has_not_keys(Tagdict, keys=["Orientation"]): continue leng = len(list(Tagdict.values())[0]) for i in range(leng): # Load the original image: model = create_model(Tagdict, i) if not subname in model.filename: continue if model.is_rotated_by(0) or not model.is_upward(): continue name = model.get_path() log().info("rotate %s", model.filename) img = Image.open(name) if model.is_rotated_by(90): img_rot = img.rotate(90 * sign, expand=True) elif model.is_rotated_by(-90): img_rot = img.rotate(-90 * sign, expand=True) else: continue NFiles += 1 if not override: name = name[:name.rfind(".")] + "_ROTATED" + name[name. rfind("."):] img_rot.save(name, 'JPEG', quality=99, exif=img.info['exif']) clock.finish()
def searchby_exiftag_equality(tag_name: str, value: str): """ searches for files where the value of the exiftag equals the input value :param tag_name: exiftag key :param value: exiftag value """ Tagdict = read_exiftags() if has_not_keys( Tagdict, keys=["Directory", "File Name", "Date/Time Original", tag_name]): return leng = len(list(Tagdict.values())[0]) files = [] for i in range(leng): if not Tagdict[tag_name][i] == value: continue files.append(getPath(Tagdict, i)) copyFilesTo(files, os.path.join(os.getcwd(), "matches"))
def searchby_exiftag_interval(tag_name: str, min_value: float, max_value: float): """ searches for files where the value of the exiftag is in the specified interval :param tag_name: exiftag key :param min_value: interval start :param max_value: interval end """ inpath = os.getcwd() Tagdict = read_exiftags(inpath) if has_not_keys(Tagdict, keys=[tag_name]): return leng = len(list(Tagdict.values())[0]) files = [] for i in range(leng): value = tofloat(Tagdict[tag_name][i]) if not (value and min_value < value < max_value): continue files.append(getPath(Tagdict, i)) copyFilesTo(files, os.path.join(inpath, "matches"))
def _detect_sunset(): """ not yet fully implemented """ inpath = os.getcwd() Tagdict = read_exiftags(inpath) if has_not_keys(Tagdict, keys=["Directory", "File Name", "Scene Mode"]): return for i in range(len(list(Tagdict.values())[0])): newDir = os.path.join(Tagdict["Directory"][i], "Sunset") os.makedirs(newDir, exist_ok=True) model = create_model(Tagdict, i) time = giveDatetime(model.get_date()) if 23 < time.hour or time.hour < 17: continue if not model.is_sun(): continue filename = getPath(Tagdict, i) if os.path.isfile(filename.replace(Tagdict["Directory"][i], newDir)): continue shutil.copy2(filename, newDir)