diff --git a/.idea/blur-exif-face-tags.iml b/.idea/blur-exif-face-tags.iml
new file mode 100644
index 0000000..6807b60
--- /dev/null
+++ b/.idea/blur-exif-face-tags.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 611bab0..181a238 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,7 +2,7 @@
-
+
\ No newline at end of file
diff --git a/README.md b/README.md
index e889923..f10d1f1 100644
--- a/README.md
+++ b/README.md
@@ -31,4 +31,4 @@ Many thanks to
* https://www.thregr.org/~wavexx/software/facedetect/#blurring-faces-within-an-image
* "Make blur all around a rectangle in image with PIL", https://stackoverflow.com/q/56987112/6334421
-* Example image: https://unsplash.com/photos/1qfy-jDc_jo?utm_source=unsplash&utm_medium=referral&utm_content=creditShareLink
\ No newline at end of file
+* Example image: https://unsplash.com/photos/1qfy-jDc_jo?utm_source=unsplash&utm_medium=referral&utm_content=creditShareLink
diff --git a/blur.py b/blur.py
index 07e0efc..7ae8916 100644
--- a/blur.py
+++ b/blur.py
@@ -12,7 +12,7 @@ import exif
class NormalizedRectangle:
"""
- x, y, width and height are normalized: Their values are in the range [0, 1]
+ x, y, width and height are normalized: Their values are in the range [0, 1].
"""
x: float
@@ -82,5 +82,19 @@ def blur_rectangle2(image_src: Path, normalized_rectangles: List[NormalizedRecta
# Save image
if image_dst is None:
- image_dst = image_src.parent.joinpath(f'{image_src.stem}_blurred{image_src.suffix}')
+ image_dst = get_image_dst(image_src)
im.save(image_dst)
+
+
+def get_image_dst(image: Path):
+ return image.parent.joinpath(f'{image.stem}{stem_suffix()}{image.suffix}')
+
+
+def stem_suffix():
+ """
+ Modified images will be saved with a different filename.
+ This suffix will be added to their stem.
+ """
+
+ # return ' [blurred]'
+ return '_blurred'
diff --git a/exif.py b/exif.py
index 0c7287f..bebb52d 100644
--- a/exif.py
+++ b/exif.py
@@ -23,19 +23,12 @@ class Image:
if len(self.files) == 0:
raise Exception
else:
- raise Exception
+ raise Exception(f'{image_file}')
def get_image_file(self):
return self.files[0]
- def get_xmp_metadata(self) -> AnyStr:
- # TODO: Try to read xmp metadata from the image file itself, if there is no sidecar xmp file
-
- xmp_sidecar = self.get_xmp_sidecar()
- with open(xmp_sidecar, "r") as f:
- return f.read()
-
- def get_xmp_sidecar(self):
+ def get_xmp_file(self):
"""
:return: The sidecar xmp file, if it exists. Otherwise None is returned.
"""
@@ -46,6 +39,17 @@ class Image:
return file
return None
+ def get_metadata_file(self):
+ """
+ If a sidecar xmp file exists, it is preferred over the image file itself.
+
+ :return: A file containing the image metadata.
+ """
+ metadata = self.get_xmp_file()
+ if metadata is None:
+ metadata = self.get_image_file()
+ return metadata
+
def __str__(self):
return f'Image: {self.__dict__}'
@@ -75,12 +79,12 @@ class ExifImageRegion:
def get_exif_image_regions(image: Image) -> List[ExifImageRegion]:
- sidecar: Path = image.get_xmp_sidecar()
+ img_metadata_file: Path = image.get_metadata_file()
- names_str = exec.execute_save(['exiftool', '-RegionName', str(sidecar)])
- r_types_str = exec.execute_save(['exiftool', '-RegionType', str(sidecar)])
- area_units_str = exec.execute_save(['exiftool', '-RegionAreaUnit', str(sidecar)])
- rectangles_str = exec.execute_save(['exiftool', '-RegionRectangle', str(sidecar)])
+ names_str = exec.execute_save(['exiftool', '-RegionName', str(img_metadata_file)])
+ r_types_str = exec.execute_save(['exiftool', '-RegionType', str(img_metadata_file)])
+ area_units_str = exec.execute_save(['exiftool', '-RegionAreaUnit', str(img_metadata_file)])
+ rectangles_str = exec.execute_save(['exiftool', '-RegionRectangle', str(img_metadata_file)])
names = names_str.strip().split(':', 1)[1].strip().split(', ')
r_types = r_types_str.strip().split(':', 1)[1].strip().split(', ')
diff --git a/main.py b/main.py
index 5873469..3cc278d 100644
--- a/main.py
+++ b/main.py
@@ -1,3 +1,4 @@
+import os
from pathlib import Path
from typing import List
@@ -29,9 +30,18 @@ def blur_image(image: exif.Image):
def main():
- for child in image_directory.iterdir():
- if child.suffix.lower() in image_extensions:
- blur_image(exif.Image(child))
+ # Convert all images in the image_directory, including subdirectories.
+ for _, _, files in os.walk(image_directory):
+ for relative_file_str in files:
+ file: Path = Path.joinpath(image_directory, relative_file_str)
+ if file.suffix.lower() in image_extensions:
+
+ if file.stem.endswith(blur.stem_suffix()):
+ print(f'Skipped the following image as it is already blurred:\n\t{file}')
+ elif blur.get_image_dst(file).exists():
+ print(f'Skipped the following image as it\'s blurred output does already exist:\n\t{file}')
+ else:
+ blur_image(exif.Image(file))
if __name__ == '__main__':