diff --git a/pount/apps/iiif/management/commands/__init__.py b/pount/apps/iiif/management/commands/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/pount/apps/iiif/management/commands/ensureiiif.py b/pount/apps/iiif/management/commands/ensureiiif.py
new file mode 100644
index 0000000000000000000000000000000000000000..510100754c7b7697b54b12c96b3a06e3023fb7c6
--- /dev/null
+++ b/pount/apps/iiif/management/commands/ensureiiif.py
@@ -0,0 +1,17 @@
+import logging
+
+from django.core.management import BaseCommand
+
+logger = logging.getLogger(__file__)
+
+
+class Command(BaseCommand):
+    def handle(self, *args, **options):
+        """
+        Lancer les tuilages manquants sur les fichiers images pour IIIF
+        """
+        from pount.apps.api.models.item import MediaFile
+        from pount.apps.iiif.tasks import ensure_media_has_iiif
+
+        for f in MediaFile.objects.filter(component="Image"):
+            ensure_media_has_iiif.delay(f.id)
diff --git a/pount/apps/iiif/storage_backends.py b/pount/apps/iiif/storage_backends.py
index 3f45cafc0c172edbadd35922ff2661c4d952fd81..a0ebdbec6090a726a0e01e5cbd65fad7a8e2eff1 100644
--- a/pount/apps/iiif/storage_backends.py
+++ b/pount/apps/iiif/storage_backends.py
@@ -5,6 +5,7 @@ from pount.apps.api.storage_backends import MediaStorage
 
 class IIIFFileStorage(MediaStorage):
     location = str(settings.CANTALOUPE_S3SOURCE_BASICLOOKUPSTRATEGY_PATH_PREFIX).rstrip("/")
+    file_overwrite = False
 
     def get_default_settings(self):
         default_settings = super().get_default_settings()
diff --git a/pount/apps/iiif/tasks.py b/pount/apps/iiif/tasks.py
index 9bc95f5c4d9b4bc2ccf06954e1a174e3cc0dc87d..fafeffb53dcd87aca3c1607bacc1f9f82b3a9aba 100644
--- a/pount/apps/iiif/tasks.py
+++ b/pount/apps/iiif/tasks.py
@@ -48,18 +48,23 @@ def ensure_media_has_iiif(media_id: Union[str, UUID]) -> None:
     media_file: MediaFile = MediaFile.objects.filter(id=media_id).first()
 
     if not media_file:
-        logger.debug(f"no such media file: {media_id}")
+        logger.info(f"no such media file: {media_id}")
         return
 
     item_media_storage = ItemMediaFileStorage()
     full_name = item_mediafile_fullname(media_file.filename, media_file.item)
 
     if not item_media_storage.exists(full_name):
-        logger.debug(f"media file not on storage: {media_id} / {full_name}")
+        logger.info(f"media file not on storage: {media_id} / {full_name}")
         return
 
+    iiif_storage = IIIFFileStorage()
+    tiled_pic_name = f"{media_file.id}.tiled.tif"
+    if iiif_storage.exists(tiled_pic_name):
+        logger.info(f"Tiled file already exists: {tiled_pic_name}")
+        return
     with tempfile.TemporaryDirectory() as tmp_dirname:
-        logger.debug(f"Start tiling in {tmp_dirname}")
+        logger.info(f"Start tiling in {tmp_dirname}")
         response = requests.get(media_file.url, stream=True)
         if response.ok:
             tmp_file_name = Path(tmp_dirname, media_file.filename)
@@ -70,7 +75,6 @@ def ensure_media_has_iiif(media_id: Union[str, UUID]) -> None:
                         f.write(chunk)
             tiled_tif = f"{basename}.tiled.tif"
             pic_to_tiled_tiff(tmp_file_name, tiled_tif)
-            iiif_storage = IIIFFileStorage()
             with open(tiled_tif, "rb") as f:
-                iiif_storage.save(f"{media_file.id}.tiled.tif", f)
-                logger.debug(f"saved {tiled_tif}")
+                iiif_storage.save(tiled_pic_name, f)
+                logger.info(f"saved {tiled_tif}")