Skip to content

Instantly share code, notes, and snippets.

@moskrc
Last active March 20, 2023 09:15
Show Gist options
  • Save moskrc/d8bb862afef72813a6dd9d3590991b28 to your computer and use it in GitHub Desktop.
Save moskrc/d8bb862afef72813a6dd9d3590991b28 to your computer and use it in GitHub Desktop.
Calculate most used focal lengths for photos
import abc
from collections import Counter
from pathlib import Path
from typing import Protocol, Iterable
from exif import Image
class BaseImageCollector(Protocol):
@property
@abc.abstractmethod
def images(self) -> Iterable[Path]:
"""Return iterable images"""
...
class ImageCollectorFileExtension(BaseImageCollector):
BASE_EXTENSIONS = ['.jpg', '.jpeg']
def __init__(self, directory: str, extensions: list[str] = None) -> None:
self.directory = directory
self.extensions = extensions or self.BASE_EXTENSIONS
def get_image_paths(self):
return [
image_path
for image_path in Path(self.directory).glob("**/*")
if image_path.suffix.lower() in self.extensions
]
@property
def images(self) -> Iterable[Path]:
for image in self.get_image_paths():
yield image
class MostUsedFocalValue:
FOCAL_LENGTHS = [
12,
16,
18,
24,
35,
50,
60,
70,
85,
135,
200,
300,
400,
500,
600,
800,
1000,
]
def __init__(self, image_collector: BaseImageCollector) -> None:
self.image_collector = image_collector
def get_focal_value(self, image_path: str) -> int:
with open(image_path, "rb") as image_file:
my_image = Image(image_file)
rounded_focal_length = round(my_image.focal_length)
return self.normalize_focal_length(rounded_focal_length)
def normalize_focal_length(self, val):
return min(self.FOCAL_LENGTHS, key=lambda x: abs(x - val))
def get_focal_values(self) -> list:
focal_values = []
for image in self.image_collector.images:
try:
focal_values.append(self.get_focal_value(image))
except (AttributeError, KeyError) as e:
print(e)
pass
return focal_values
def count_focal_values(self, focal_values: list) -> dict:
counter = Counter(focal_values)
return counter.most_common()
def calculate(self):
focal_values = self.get_focal_values()
return self.count_focal_values(focal_values)
if __name__ == "__main__":
path = "images"
image_collector = ImageCollectorFileExtension(path, extensions=[".jpg", ".jpeg", ".raf"])
print('Total images:', len(list(image_collector.images)))
av = MostUsedFocalValue(image_collector)
print(av.calculate())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment