diff --git a/ingestors/media/image.py b/ingestors/media/image.py
index af358397e..2633745b4 100644
--- a/ingestors/media/image.py
+++ b/ingestors/media/image.py
@@ -1,6 +1,7 @@
 import logging
 from io import BytesIO
 from PIL import Image, ExifTags
+from pillow_heif import register_heif_opener
 from followthemoney import model
 
 from ingestors.ingestor import Ingestor
@@ -56,6 +57,7 @@ def extract_exif(self, img, entity):
                 entity.add("generator", value)
 
     def ingest(self, file_path, entity):
+        register_heif_opener()
         entity.schema = model.get("Image")
         with open(file_path, "rb") as fh:
             data = fh.read()
diff --git a/requirements.txt b/requirements.txt
index 3c73e9997..d6da35df2 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -30,6 +30,7 @@ cchardet==2.1.7
 lxml==5.0.0
 olefile==0.47
 Pillow==10.1.0
+pillow-heif==0.15.0
 vobject==0.9.6.1
 msglite==0.30.0
 icalendar==5.0.11
diff --git a/tests/fixtures/image1.heic b/tests/fixtures/image1.heic
new file mode 100644
index 000000000..7ba28200e
Binary files /dev/null and b/tests/fixtures/image1.heic differ
diff --git a/tests/test_image.py b/tests/test_image.py
index dd4f03147..15a0735f1 100644
--- a/tests/test_image.py
+++ b/tests/test_image.py
@@ -91,3 +91,12 @@ def test_tesseract_ocr_regression(self):
                     image_entity.first("indexText"),
                     f"Test failed for {test_data[test_image_type]['file']}",
                 )
+
+    def test_ingest_heif(self):
+        fixture_path, entity = self.fixture("image1.heic")
+        self.manager.ingest(fixture_path, entity)
+
+        self.assertEqual(
+            entity.first("processingStatus"),
+            self.manager.STATUS_SUCCESS,
+        )