diff --git a/app/models/template.py b/app/models/template.py index ad3f90dd9..56a629acf 100644 --- a/app/models/template.py +++ b/app/models/template.py @@ -222,7 +222,7 @@ async def create(cls, url: str, *, force=False) -> "Template": logger.warning(f"Unable to determine image extension: {url}") suffix = settings.PLACEHOLDER_SUFFIX - filename = "default" + suffix + filename = ("animated" if suffix == ".gif" else "default") + suffix path = aiopath.AsyncPath(template.directory) / filename if await path.exists() and not settings.DEBUG and not force: diff --git a/app/tests/images/_custom-8c07e54720f56695b9d07ff388a553e7380e17b6/this_isn't_the_GIF/you're_looking_for.19ce359e2f5320aefdf2a71250cacb29d0130578.gif b/app/tests/images/_custom-8c07e54720f56695b9d07ff388a553e7380e17b6/this_isn't_the_GIF/you're_looking_for.19ce359e2f5320aefdf2a71250cacb29d0130578.gif new file mode 100644 index 000000000..dfff81172 Binary files /dev/null and b/app/tests/images/_custom-8c07e54720f56695b9d07ff388a553e7380e17b6/this_isn't_the_GIF/you're_looking_for.19ce359e2f5320aefdf2a71250cacb29d0130578.gif differ diff --git a/app/tests/images/_custom-95adba7864bc0608374810deec55976a4e661e57/this_is/animated.f758951228f4c53c2b0348a12f4db56ca39e4c85.gif b/app/tests/images/_custom-95adba7864bc0608374810deec55976a4e661e57/this_is/animated.f758951228f4c53c2b0348a12f4db56ca39e4c85.gif index b0849b21d..6376104fb 100644 Binary files a/app/tests/images/_custom-95adba7864bc0608374810deec55976a4e661e57/this_is/animated.f758951228f4c53c2b0348a12f4db56ca39e4c85.gif and b/app/tests/images/_custom-95adba7864bc0608374810deec55976a4e661e57/this_is/animated.f758951228f4c53c2b0348a12f4db56ca39e4c85.gif differ diff --git a/app/tests/images/cbg/_/not._animated._ever.f758951228f4c53c2b0348a12f4db56ca39e4c85.gif b/app/tests/images/cbg/_/not._animated._ever.f758951228f4c53c2b0348a12f4db56ca39e4c85.gif index 98e015afb..bfa574e75 100644 Binary files a/app/tests/images/cbg/_/not._animated._ever.f758951228f4c53c2b0348a12f4db56ca39e4c85.gif and b/app/tests/images/cbg/_/not._animated._ever.f758951228f4c53c2b0348a12f4db56ca39e4c85.gif differ diff --git a/app/tests/images/iw/tests_code/in_production_(debug).a93ae473d60f658f0225ebcf1d8e9c27d9b4ef4a.gif b/app/tests/images/iw/tests_code/in_production_(debug).a93ae473d60f658f0225ebcf1d8e9c27d9b4ef4a.gif index 9be36516e..89932b22e 100644 Binary files a/app/tests/images/iw/tests_code/in_production_(debug).a93ae473d60f658f0225ebcf1d8e9c27d9b4ef4a.gif and b/app/tests/images/iw/tests_code/in_production_(debug).a93ae473d60f658f0225ebcf1d8e9c27d9b4ef4a.gif differ diff --git a/app/tests/test_utils_images.py b/app/tests/test_utils_images.py index 299f9686f..2165e92c1 100644 --- a/app/tests/test_utils_images.py +++ b/app/tests/test_utils_images.py @@ -269,6 +269,17 @@ def test_debug_images(images, monkeypatch, extension): ) +@pytest.mark.slow +@pytest.mark.asyncio +async def test_debug_images_with_slow_background(images, monkeypatch): + monkeypatch.setattr(settings, "DEBUG", True) + + url = "https://media.giphy.com/media/4560Nv2656Gv0Lvp9F/giphy.gif" + template = await models.Template.create(url) + lines = ["this isn't the GIF", "you're looking for"] + utils.images.save(template, lines, style=url, extension="gif", directory=images) + + def test_deployed_images(images, monkeypatch): monkeypatch.setattr(settings, "DEPLOYED", True) diff --git a/app/utils/images.py b/app/utils/images.py index c4058131b..79db33635 100644 --- a/app/utils/images.py +++ b/app/utils/images.py @@ -83,8 +83,12 @@ def save( count = len(frames) if (count <= settings.MINIMUM_FRAMES) or (count > settings.MAXIMUM_FRAMES): - logger.info(f"Saving {count} frame(s) as animated PNG") + logger.info( + f"Saving {count} frame(s) as animated PNG at {duration} duration" + ) extension = "png" + else: + logger.info(f"Saving {count} frame(s) as GIF at {duration} duration") frames[0].save( path, @@ -248,7 +252,7 @@ def render_animation( elif sum(1 for line in lines if line.strip()) >= 2: template.animate() sources = [source] * settings.MINIMUM_FRAMES # type: ignore - duration = 300 + duration = 1200 total = settings.MINIMUM_FRAMES else: sources = [source] # type: ignore @@ -337,12 +341,16 @@ def render_animation( image = add_watermark(image, ".", is_preview, index, total) if settings.DEBUG: - image = add_counter(image, index, total, modulus) + image = add_counter(image, index, total, modulus, duration) frames.append(image) - ratio = len(frames) / max(total, settings.MAXIMUM_FRAMES) - duration = duration / ratio + if len(frames) > settings.MINIMUM_FRAMES: + logger.info( + f"Adjusting initial duration of {duration} based on {total} initial frame(s)" + ) + ratio = len(frames) / max(total, settings.MAXIMUM_FRAMES) + duration = min(250, duration / ratio) return frames, duration @@ -444,9 +452,11 @@ def add_watermark( return Image.alpha_composite(image, box) -def add_counter(image: ImageType, index: int, total: int, modulus: float) -> ImageType: +def add_counter( + image: ImageType, index: int, total: int, modulus: float, duration: int +) -> ImageType: size = (image.size[0], settings.WATERMARK_HEIGHT) - text = f"{index+1:02} of {total:02} / {modulus}" + text = f"{index+1:02} of {total:02} / {modulus} @ {duration}" font = get_font("tiny", text, size, 99) box = Image.new("RGBA", image.size)