From fdbe5ced95d198740cdae3007ffb5f0c3a00233e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Bl=C3=B6chl?= Date: Sun, 26 May 2024 20:10:08 +0200 Subject: [PATCH 1/6] Load pillow_heif if available --- pyproject.toml | 2 +- src/sigal/image.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a4869612..83d3783d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ dependencies = [ dynamic = ["version"] [project.optional-dependencies] -all = ["brotli", "feedgenerator", "zopfli", "cryptography"] +all = ["brotli", "feedgenerator", "zopfli", "cryptography", "pillow-heif"] tests = ["pytest", "pytest-cov"] docs = ["Sphinx>=4.1.0", "furo", "cryptography"] diff --git a/src/sigal/image.py b/src/sigal/image.py index 83a994ae..291b84a7 100644 --- a/src/sigal/image.py +++ b/src/sigal/image.py @@ -44,6 +44,11 @@ from pilkit.processors import Transpose from pilkit.utils import save_image +try: + from pillow_heif import HeifImagePlugin +except: + pass + from . import signals, utils # Force loading of truncated files From d23ac679bb841afa3070ef2476396d6359b91a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Bl=C3=B6chl?= Date: Sun, 26 May 2024 20:10:08 +0200 Subject: [PATCH 2/6] Add support for EXIF data in .heic files --- src/sigal/gallery.py | 4 ++-- src/sigal/image.py | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sigal/gallery.py b/src/sigal/gallery.py index 51cb5d71..8ca5e010 100644 --- a/src/sigal/gallery.py +++ b/src/sigal/gallery.py @@ -264,7 +264,7 @@ def exif(self): datetime_format = self.settings["datetime_format"] return ( get_exif_tags(self.raw_exif, datetime_format=datetime_format) - if self.raw_exif and self.src_ext in (".jpg", ".jpeg") + if self.raw_exif and self.src_ext in (".jpg", ".jpeg", ".heic") else None ) @@ -289,7 +289,7 @@ def _get_markdown_metadata(self): @cached_property def raw_exif(self): """If not `None`, contains the raw EXIF tags.""" - if self.src_ext in (".jpg", ".jpeg"): + if self.src_ext in (".jpg", ".jpeg", ".heic"): return self.file_metadata["exif"] @cached_property diff --git a/src/sigal/image.py b/src/sigal/image.py index 291b84a7..4996125d 100644 --- a/src/sigal/image.py +++ b/src/sigal/image.py @@ -225,7 +225,10 @@ def get_exif_data(filename): try: with warnings.catch_warnings(record=True) as caught_warnings: - exif = img._getexif() or {} + exif = {} + exifdata = img.getexif() + if exifdata: + exif = exifdata._get_merged_dict() except ZeroDivisionError: logger.warning("Failed to read EXIF data.") return None @@ -295,7 +298,7 @@ def get_image_metadata(filename): logger.error("Could not open image %s metadata: %s", filename, e) else: try: - if os.path.splitext(filename)[1].lower() in (".jpg", ".jpeg"): + if os.path.splitext(filename)[1].lower() in (".jpg", ".jpeg", ".heic"): exif = get_exif_data(img) except Exception as e: logger.warning("Could not read EXIF data from %s: %s", filename, e) From 01e178015ad947c839f7c53665ff56f5f3eeb016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Bl=C3=B6chl?= Date: Sat, 2 Nov 2024 17:19:51 +0100 Subject: [PATCH 3/6] Add a basic test for .heic exif metadata --- tests/sample/pictures/dir1/test1/outdoor.heic | Bin 0 -> 73108 bytes tests/test_image.py | 9 +++++++++ 2 files changed, 9 insertions(+) create mode 100644 tests/sample/pictures/dir1/test1/outdoor.heic diff --git a/tests/sample/pictures/dir1/test1/outdoor.heic b/tests/sample/pictures/dir1/test1/outdoor.heic new file mode 100644 index 0000000000000000000000000000000000000000..2632594c4c77181289e2fd80a282f800a8038264 GIT binary patch literal 73108 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 Date: Mon, 9 Dec 2024 21:49:34 +0100 Subject: [PATCH 4/6] activate .heic by default and log warn if pillow_heif is missing --- src/sigal/gallery.py | 12 +++++++++--- src/sigal/image.py | 20 +++++++++++++++----- src/sigal/settings.py | 11 ++++++++++- src/sigal/templates/sigal.conf.py | 2 +- tests/test_gallery.py | 2 +- tests/test_image.py | 3 +++ 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/sigal/gallery.py b/src/sigal/gallery.py index 8ca5e010..addddb2a 100644 --- a/src/sigal/gallery.py +++ b/src/sigal/gallery.py @@ -45,7 +45,13 @@ from PIL import Image as PILImage from . import image, signals, video -from .image import get_exif_tags, get_image_metadata, get_size, process_image +from .image import ( + EXIF_EXTENSIONS, + get_exif_tags, + get_image_metadata, + get_size, + process_image, +) from .settings import Status, get_thumb from .utils import ( Devnull, @@ -264,7 +270,7 @@ def exif(self): datetime_format = self.settings["datetime_format"] return ( get_exif_tags(self.raw_exif, datetime_format=datetime_format) - if self.raw_exif and self.src_ext in (".jpg", ".jpeg", ".heic") + if self.raw_exif and self.src_ext in EXIF_EXTENSIONS else None ) @@ -289,7 +295,7 @@ def _get_markdown_metadata(self): @cached_property def raw_exif(self): """If not `None`, contains the raw EXIF tags.""" - if self.src_ext in (".jpg", ".jpeg", ".heic"): + if self.src_ext in EXIF_EXTENSIONS: return self.file_metadata["exif"] @cached_property diff --git a/src/sigal/image.py b/src/sigal/image.py index 4996125d..f7d154b6 100644 --- a/src/sigal/image.py +++ b/src/sigal/image.py @@ -45,15 +45,20 @@ from pilkit.utils import save_image try: - from pillow_heif import HeifImagePlugin -except: - pass + from pillow_heif import HeifImagePlugin # noqa: F401 + + HAS_HEIF = True +except ImportError: + HAS_HEIF = False from . import signals, utils +from .settings import Status # Force loading of truncated files ImageFile.LOAD_TRUNCATED_IMAGES = True +EXIF_EXTENSIONS = (".jpg", ".jpeg", ".heic") + def _has_exif_tags(img): return hasattr(img, "info") and "exif" in img.info @@ -71,7 +76,7 @@ def _read_image(file_path): for w in caught_warnings: logger.warning( - f"PILImage reported a warning for file {file_path}\n" + f"Pillow reported a warning for file {file_path}\n" f"{w.category}: {w.message}" ) return im @@ -185,6 +190,11 @@ def process_image(media): options = media.settings["jpg_options"] elif media.src_ext == ".png": options = {"optimize": True} + elif media.src_ext == ".heic" and not HAS_HEIF: + logger.warning( + f"cannot open {media.src_path}, pillow-heif is needed to open .heic files" + ) + return Status.FAILURE else: options = {} @@ -298,7 +308,7 @@ def get_image_metadata(filename): logger.error("Could not open image %s metadata: %s", filename, e) else: try: - if os.path.splitext(filename)[1].lower() in (".jpg", ".jpeg", ".heic"): + if os.path.splitext(filename)[1].lower() in EXIF_EXTENSIONS: exif = get_exif_data(img) except Exception as e: logger.warning("Could not read EXIF data from %s: %s", filename, e) diff --git a/src/sigal/settings.py b/src/sigal/settings.py index 2ed1b4fd..c26be32e 100644 --- a/src/sigal/settings.py +++ b/src/sigal/settings.py @@ -42,7 +42,16 @@ "google_tag_manager": "", "ignore_directories": [], "ignore_files": [], - "img_extensions": [".jpg", ".jpeg", ".png", ".gif", ".tif", ".tiff", ".webp"], + "img_extensions": [ + ".jpg", + ".jpeg", + ".png", + ".gif", + ".heic", + ".tif", + ".tiff", + ".webp", + ], "img_processor": "ResizeToFit", "img_size": (640, 480), "img_format": None, diff --git a/src/sigal/templates/sigal.conf.py b/src/sigal/templates/sigal.conf.py index 77505a6f..4c02597d 100644 --- a/src/sigal/templates/sigal.conf.py +++ b/src/sigal/templates/sigal.conf.py @@ -66,7 +66,7 @@ # map_height = '500px' # File extensions that should be treated as images -# img_extensions = ['.jpg', '.jpeg', '.png', '.gif'] +# img_extensions = [".jpg", ".jpeg", ".png", ".gif", ".heic", ".tif", ".tiff", ".webp"] # Pilkit processor used to resize the image # (see http://pilkit.readthedocs.org/en/latest/#processors) diff --git a/tests/test_gallery.py b/tests/test_gallery.py index cf6978c2..31489f01 100644 --- a/tests/test_gallery.py +++ b/tests/test_gallery.py @@ -301,7 +301,7 @@ def test_gallery(settings, tmp_path, caplog): gal = Gallery(settings, ncpu=1) gal.build() - assert re.match(r"CSS file .* could not be found", caplog.records[3].message) + assert re.match(r"CSS file .* could not be found", caplog.records[4].message) with open(tmp_path / "my.css", mode="w") as f: f.write("color: red") diff --git a/tests/test_image.py b/tests/test_image.py index 34298aad..fac4fc84 100644 --- a/tests/test_image.py +++ b/tests/test_image.py @@ -201,7 +201,9 @@ def test_get_exif_tags(): assert "datetime" not in simple assert "gps" not in simple + def test_get_heic_exif_tags(): + pytest.importorskip("pillow_heif") test_image = "outdoor.heic" src_file = os.path.join( CURRENT_DIR, "sample", "pictures", "dir1", "test1", test_image @@ -211,6 +213,7 @@ def test_get_heic_exif_tags(): assert simple["Make"] == "samsung" assert simple["datetime"] == "01/09/2024" + def test_get_iptc_data(caplog): test_image = "1.jpg" src_file = os.path.join(CURRENT_DIR, "sample", "pictures", "iptcTest", test_image) From 3492320fc6bf5d365ed7747b3319301f472598c9 Mon Sep 17 00:00:00 2001 From: Simon Conseil Date: Mon, 9 Dec 2024 21:57:37 +0100 Subject: [PATCH 5/6] fix test --- tests/test_gallery.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/test_gallery.py b/tests/test_gallery.py index 31489f01..7ff334c1 100644 --- a/tests/test_gallery.py +++ b/tests/test_gallery.py @@ -10,6 +10,13 @@ from sigal.gallery import Album, Gallery, Image, Media, Video from sigal.video import SubprocessException +try: + from pillow_heif import HeifImagePlugin # noqa: F401 + + HAS_HEIF = True +except ImportError: + HAS_HEIF = False + CURRENT_DIR = os.path.dirname(__file__) REF = { @@ -301,7 +308,11 @@ def test_gallery(settings, tmp_path, caplog): gal = Gallery(settings, ncpu=1) gal.build() - assert re.match(r"CSS file .* could not be found", caplog.records[4].message) + + if HAS_HEIF: + assert re.match(r"CSS file .* could not be found", caplog.records[3].message) + else: + assert re.match(r"CSS file .* could not be found", caplog.records[4].message) with open(tmp_path / "my.css", mode="w") as f: f.write("color: red") From 536f658abbed9e6d040d4b90c6a1f82d04fa66c9 Mon Sep 17 00:00:00 2001 From: Simon Conseil Date: Mon, 9 Dec 2024 22:04:31 +0100 Subject: [PATCH 6/6] fix another test --- tests/test_zip.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/test_zip.py b/tests/test_zip.py index a5450cc9..ea098b6d 100644 --- a/tests/test_zip.py +++ b/tests/test_zip.py @@ -24,16 +24,11 @@ def test_zipped_correctly(tmpdir): gallery = make_gallery(destination=outpath, zip_gallery="archive.zip") gallery.build() - zipf = os.path.join(outpath, "test1", "archive.zip") + zipf = os.path.join(outpath, "test2", "archive.zip") assert os.path.isfile(zipf) zip_file = zipfile.ZipFile(zipf, "r") - expected = ( - "11.jpg", - "CMB_Timeline300_no_WMAP.jpg", - "flickr_jerquiaga_2394751088_cc-by-nc.jpg", - "example.gif", - ) + expected = ("21.tiff", "22.jpg", "CMB_Timeline300_no_WMAP.jpg") for filename in zip_file.namelist(): assert filename in expected