From 01e0cd9dac085d62b0889d241007ff9b47a3fbf2 Mon Sep 17 00:00:00 2001 From: frmdstryr Date: Wed, 1 May 2019 08:33:02 -0400 Subject: [PATCH] Support format-webp and allow changing default formatting --- .../images/image_file_formats.rst | 45 +++++++++++++++++++ docs/advanced_topics/images/index.rst | 1 + wagtail/images/image_operations.py | 5 ++- wagtail/images/models.py | 25 ++++++----- wagtail/images/tests/test_image_operations.py | 10 +++++ 5 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 docs/advanced_topics/images/image_file_formats.rst diff --git a/docs/advanced_topics/images/image_file_formats.rst b/docs/advanced_topics/images/image_file_formats.rst new file mode 100644 index 000000000..605f4886e --- /dev/null +++ b/docs/advanced_topics/images/image_file_formats.rst @@ -0,0 +1,45 @@ +Image file formats +================== + +Using the picture element +------------------------- + +The `picture element `_ +can be used with the ``format-`` image operation to specify different +image formats and let the browser choose the one it prefers. For example: + +.. code-block:: python + + {% load wagtailimages_tags %} + + + {% image myimage width-1000 format-webp as image_webp %} + + + {% image myimage width-1000 format-png as image_png %} + + + {{ image_png }} + + +Customizing output formats +-------------------------- + +By default all ``bmp`` and ``webp`` images are converted to the ``png`` format +when no image output format is given. + +The default conversion mapping can be changed by setting the +``WAGTAILIMAGES_FORMAT_CONVERSIONS`` to a dictionary which maps the input type +to an output type. + +For example: + +.. code-block:: python + + WAGTAILIMAGES_FORMAT_CONVERSIONS = { + 'bmp': 'jpeg', + 'webp': 'webp', + } + +will convert ``bmp`` images to ``jpeg`` and disable the default ``webp`` +to ``png`` conversion. diff --git a/docs/advanced_topics/images/index.rst b/docs/advanced_topics/images/index.rst index d6d6b8642..b971c24c9 100644 --- a/docs/advanced_topics/images/index.rst +++ b/docs/advanced_topics/images/index.rst @@ -7,6 +7,7 @@ Images renditions animated_gifs + image_file_formats custom_image_model changing_rich_text_representation feature_detection diff --git a/wagtail/images/image_operations.py b/wagtail/images/image_operations.py index 9964e3d87..9eb955888 100644 --- a/wagtail/images/image_operations.py +++ b/wagtail/images/image_operations.py @@ -246,8 +246,9 @@ class FormatOperation(Operation): def construct(self, fmt): self.format = fmt - if self.format not in ['jpeg', 'png', 'gif']: - raise ValueError("Format must be either 'jpeg', 'png' or 'gif'") + if self.format not in ['jpeg', 'png', 'gif', 'webp']: + raise ValueError( + "Format must be either 'jpeg', 'png', 'gif', or 'webp'") def run(self, willow, image, env): env['output-format'] = self.format diff --git a/wagtail/images/models.py b/wagtail/images/models.py index 424786e21..985de2131 100644 --- a/wagtail/images/models.py +++ b/wagtail/images/models.py @@ -404,20 +404,23 @@ class Filter: # Developer specified an output format output_format = env['output-format'] else: - # Default to outputting in original format - output_format = original_format - - # Convert BMP files to PNG - if original_format == 'bmp': - output_format = 'png' + # Convert bmp and webp to png by default + default_conversions = { + 'bmp': 'png', + 'webp': 'png', + } # Convert unanimated GIFs to PNG as well - if original_format == 'gif' and not willow.has_animation(): - output_format = 'png' + if not willow.has_animation(): + default_conversions['gif'] = 'png' - # Convert WEBP files to PNG - if original_format == 'webp': - output_format = 'png' + # Allow the user to override the conversions + conversion = getattr(settings, 'WAGTAILIMAGES_FORMAT_CONVERSIONS', {}) + default_conversions.update(conversion) + + # Get the converted output format falling back to the original + output_format = default_conversions.get( + original_format, original_format) if output_format == 'jpeg': # Allow changing of JPEG compression quality diff --git a/wagtail/images/tests/test_image_operations.py b/wagtail/images/tests/test_image_operations.py index d91ae86ee..78c718df9 100644 --- a/wagtail/images/tests/test_image_operations.py +++ b/wagtail/images/tests/test_image_operations.py @@ -521,6 +521,16 @@ class TestFormatFilter(TestCase): self.assertEqual(out.format_name, 'gif') + def test_webp(self): + fil = Filter(spec='width-400|format-webp') + image = Image.objects.create( + title="Test image", + file=get_test_image_file(), + ) + out = fil.run(image, BytesIO()) + + self.assertEqual(out.format_name, 'webp') + def test_invalid(self): fil = Filter(spec='width-400|format-foo') image = Image.objects.create(