django-versatileimagefield icon indicating copy to clipboard operation
django-versatileimagefield copied to clipboard

Change file format in templates

Open hovi opened this issue 1 year ago • 4 comments

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.

hovi avatar Sep 26 '24 11:09 hovi

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

MikeSoft avatar Dec 08 '24 22:12 MikeSoft

@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!

respondcreate avatar Dec 09 '24 00:12 respondcreate

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.

hovi avatar Dec 10 '24 11:12 hovi

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?

dan-bowen avatar Jan 26 '25 19:01 dan-bowen