Skip to content

adding HEIC and JPEG-XL format support via optional plugin dependencies #123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.py[oc]
.DS_Store
/*.egg-info/
/dist/
__pycache__/
difPy_*.json
difPy_*_lower_quality.txt
Thumbs.db
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

```python
pip install difPy

# with plugins for additional image formats (HEIC, JPEG-XL, etc.)
pip install 'difPy[plugins]'
```

> ✨🚀 **Join the [difPy for Desktop beta tester](https://difpy.short.gy/desktop-beta-ghb) program and be among to first to test the new difPy desktop app!**
Expand Down Expand Up @@ -156,6 +159,7 @@ difPy.search(difpy_obj, similarity='duplicates', rotate=True, same_dim=True, sho
## CLI Usage
difPy can also be invoked through the CLI by using the following commands:

### From Source
```python
python dif.py #working directory

Expand All @@ -164,6 +168,15 @@ python dif.py -D 'C:/Path/to/Folder/'
python dif.py -D 'C:/Path/to/Folder_A/' 'C:/Path/to/Folder_B/' 'C:/Path/to/Folder_C/'
```

### Installed Package
```shell
pip install difPy

difpy
# or
python -m difpy
```

> :point_right: Windows users can add difPy to their [PATH system variables](https://www.computerhope.com/issues/ch000549.htm) by pointing it to their difPy package installation folder containing the [`difPy.bat`](https://github.com/elisemercury/Duplicate-Image-Finder/difPy/difPy.bat) file. This adds `difPy` as a command in the CLI and will allow direct invocation of `difPy` from anywhere on the device.

difPy CLI supports the following arguments:
Expand Down
4 changes: 4 additions & 0 deletions difPy/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .dif import cli

if __name__ == '__main__':
cli()
41 changes: 30 additions & 11 deletions difPy/dif.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,28 @@
2024 Elise Landman
https://github.com/elisemercury/Duplicate-Image-Finder
'''
from glob import glob
from multiprocessing import Pool, current_process, freeze_support
import numpy as np
from PIL import Image
import os
from datetime import datetime
from pathlib import Path
import argparse
import contextlib
import json
import os
import sys
import warnings
from itertools import combinations
from collections import defaultdict
from datetime import datetime
from glob import glob
from itertools import combinations
from multiprocessing import Pool, current_process, freeze_support
from pathlib import Path

import numpy as np
from PIL import Image

# Optional plugins
with contextlib.suppress(ImportError):
import pillow_jxl
with contextlib.suppress(ImportError):
from pillow_heif import register_heif_opener
register_heif_opener()

def _initialize_multiprocessing():
# Function that initializes multiprocessing
Expand Down Expand Up @@ -161,6 +171,12 @@ def _validate_files(self, directory):
def _filter_extensions(self, directory_files):
# Function that filters by files with a specific filetype
valid_extensions = np.array(['apng', 'bw', 'cdf', 'cur', 'dcx', 'dds', 'dib', 'emf', 'eps', 'fli', 'flc', 'fpx', 'ftex', 'fits', 'gd', 'gd2', 'gif', 'gbr', 'icb', 'icns', 'iim', 'ico', 'im', 'imt', 'j2k', 'jfif', 'jfi', 'jif', 'jp2', 'jpe', 'jpeg', 'jpg', 'jpm', 'jpf', 'jpx', 'jpeg', 'mic', 'mpo', 'msp', 'nc', 'pbm', 'pcd', 'pcx', 'pgm', 'png', 'ppm', 'psd', 'pixar', 'ras', 'rgb', 'rgba', 'sgi', 'spi', 'spider', 'sun', 'tga', 'tif', 'tiff', 'vda', 'vst', 'wal', 'webp', 'xbm', 'xpm'])
# Add additional extensions from plugins
if 'pillow_jxl' in sys.modules:
valid_extensions = np.append(valid_extensions, ['jxl'])
if 'pillow_heif' in sys.modules:
valid_extensions = np.append(valid_extensions, ['heic', 'heif'])

extensions = list()
for file in directory_files:
try:
Expand Down Expand Up @@ -971,8 +987,8 @@ def _strtobool(v):
return False
else:
raise argparse.ArgumentTypeError('Boolean value expected')
if __name__ == '__main__':

def cli():
# Parameters for when launching difPy via CLI
parser = argparse.ArgumentParser(description='Find duplicate or similar images with difPy - https://github.com/elisemercury/Duplicate-Image-Finder')
parser.add_argument('-D', '--directory', type=str, nargs='+', help='Paths of the directories to be searched. Default is working dir.', required=False, default=[os.getcwd()])
Expand Down Expand Up @@ -1040,4 +1056,7 @@ def _strtobool(v):
# delete search.lower_quality files
se.delete(silent_del=args.silent_del)

print(f'''\n{result_file}\n{lq_file}\n{stats_file}\n\nsaved in '{dir}'.''')
print(f'''\n{result_file}\n{lq_file}\n{stats_file}\n\nsaved in '{dir}'.''')

if __name__ == '__main__':
cli()
41 changes: 41 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[project]
name = "difpy"
dynamic = ["version"]
description = "Duplicate Image Finder - Python package for finding duplicate and similar images"
readme = "README.md"
keywords = ["duplicate", "image", "finder", "similarity", "pictures"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3.11",
"Topic :: Software Development :: Build Tools"
]
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26.4",
"pillow>=10.2.0",
]

[project.urls]
homepage = "https://github.com/elisemercury/Duplicate-Image-Finder"
documentation = "https://difpy.readthedocs.io"
repository = "https://github.com/elisemercury/Duplicate-Image-Finder"

[project.optional-dependencies]
jxl = ["pillow-jxl-plugin>=1.3.2"]
heic = ["pillow-heif>=0.21.0"]
plugins = [
"difpy[jxl]",
"difpy[heic]",
]

[project.scripts]
difpy = "difPy.dif:cli"

[tool.setuptools]
packages = ["difPy"]

[tool.setuptools.dynamic]
version = {attr = "difPy.version.__version__"}
Loading