Browse Source

activate .heic by default and log warn if pillow_heif is missing

pull/519/head
Simon Conseil 1 year ago
parent
commit
8c8a6a2040
  1. 12
      src/sigal/gallery.py
  2. 20
      src/sigal/image.py
  3. 11
      src/sigal/settings.py
  4. 2
      src/sigal/templates/sigal.conf.py
  5. 2
      tests/test_gallery.py
  6. 3
      tests/test_image.py

12
src/sigal/gallery.py

@ -45,7 +45,13 @@ from natsort import natsort_keygen, ns
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 @@ class Image(Media):
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 @@ class Image(Media):
@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

20
src/sigal/image.py

@ -45,15 +45,20 @@ from pilkit.processors import Transpose
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)

11
src/sigal/settings.py

@ -42,7 +42,16 @@ _DEFAULT_CONFIG = {
"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,

2
src/sigal/templates/sigal.conf.py

@ -66,7 +66,7 @@ img_size = (800, 600)
# 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)

2
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")

3
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)

Loading…
Cancel
Save