Change file format in templates
As part of my frontend optimization, I would like to convert all my images to webp, while keeping my source images in their original format. I was thinking of doing this as part of versatileimagefield filters in template as that pipeline is already resizing and cropping images. But I saw there is no built-in option and when going through code it seems like the output format is pretty much hardcoded and the whole part seems to be built with the idea that the format and extension doesn't change the whole time.
Is that correct? What is opinion of creators? Should I solve this outside of versatileimagefield or do you consider something as feature that could be added? I don't mind making a PR.
reading the documentation, there's an alternative, you can create your own image proccessor. https://django-versatileimagefield.readthedocs.io/en/latest/writing_custom_sizers_and_filters.html
@hovi Yeah, when I first wrote this library I didn't even consider changing the file format when sizing/creating images. It has been quite a long time since I've done any active development on this project besides the occasional Django upgrade housekeeping work.
If you want to open a PR, I'd be more than happy to review it, just make sure everything you do is covered by tests!
reading the documentation, there's an alternative, you can create your own image proccessor. https://django-versatileimagefield.readthedocs.io/en/latest/writing_custom_sizers_and_filters.html
Yeah, documentation may suggest that, but in reality it doesn't allow changing file format properly when creating custom image processors.
I am looking at webp conversion now also and may be encountering the same issue. This is my first attempt to create a filter to do the conversion.
class WebPFilter(FilteredImage):
"""
Convert the image to webp format
"""
def process_image(self, image, image_format, save_kwargs={}):
"""Return a BytesIO instance of `image` converted to webp"""
# 1. Create an in-memory buffer to store the converted image data
buffer = BytesIO()
# 2. Filter operations
save_kwargs['format'] = 'WebP'
# 3. Save image
image.save(
buffer,
**save_kwargs
)
# 4. Return the buffer
return buffer
versatileimagefield_registry.register_filter('webp', WebPFilter)
Then in the template (on-demand) I am doing this:
{{ slide.image.filters.webp.crop.800x600 }}
It does save to webp format but with the pre-existing extension of .jpg.
file --mime "media/__sized__/images/carousel-v1/2025-01-25/__filtered__/5aea282e-766f-4440-bf70-197661c8fe2a__webp__-crop-c0-5__0-5-200x200-100.jpg"
media/__sized__/images/carousel-v1/2025-01-25/__filtered__/5aea282e-766f-4440-bf70-197661c8fe2a__webp__-crop-c0-5__0-5-200x200-100.jpg: image/webp; charset=binary
Is there a way for a filter or sizer to change the extension?