Skip to content

Instantly share code, notes, and snippets.

@i-v-s
Created October 3, 2022 10:00
Show Gist options
  • Save i-v-s/476344d68c774aac75805fef1964854f to your computer and use it in GitHub Desktop.
Save i-v-s/476344d68c774aac75805fef1964854f to your computer and use it in GitHub Desktop.
from typing import NamedTuple
from pathlib import Path
from argparse import ArgumentParser
from shutil import move
from imghdr import what
from hashlib import sha1
import cv2
ext_map = {
'jpeg': 'jpg',
}
hash_map = {}
class Info(NamedTuple):
fn: Path
shape: tuple[int, int, int]
size: int
def better_than(self, other: 'Info') -> bool:
w, h, *_ = self.shape
ow, oh, *_ = other.shape
if w > ow or h > oh:
return True
elif w < ow or h < oh:
return False
else:
return self.size > other.size
def check_image(fn: Path, target_size=(320, 240)) -> None:
image = cv2.imread(str(fn))
if image is None:
print('Unable to read', fn)
return
shape = image.shape
image = cv2.resize(image, target_size)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.normalize(image, None, alpha=0, beta=3, norm_type=cv2.NORM_MINMAX)
h = sha1(image.data).hexdigest()
file_size = fn.stat().st_size
new_item = Info(fn, shape, file_size)
if item := hash_map.get(h, False):
if not new_item.better_than(item):
new_item, item = item, new_item
hash_map[h] = new_item
print(f'Deleting {item.fn} as copy of {new_item.fn}')
item.fn.unlink()
#cv2.imshow('TEST', image * 64)
#cv2.waitKey(-1)
else:
hash_map[h] = new_item
def main():
parser = ArgumentParser('Images fixer')
parser.add_argument('source', type=Path, help='Images directory')
args = parser.parse_args()
src_dir: Path = args.source
for item in src_dir.glob('**/*'):
if item.is_file() and (t := what(item)) is not None:
ext = f'.{ext_map.get(t, t)}'
if item.suffix != ext:
new_name = item.with_suffix(ext)
i = 1
while new_name.is_file():
new_name = new_name.with_stem(f'{new_name.stem}_{i}')
i += 1
print(f'Rename {item} to {new_name}')
move(item, new_name)
item = new_name
check_image(item)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment