Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Add AVIF support. #1202

Open
BezPowell opened this issue Oct 7, 2020 · 8 comments
Open

Feature request: Add AVIF support. #1202

BezPowell opened this issue Oct 7, 2020 · 8 comments

Comments

@BezPowell
Copy link
Contributor

Adding this as a feature request now as image-rs seem to be well advanced with their avif support: image-rs/image#1152
The original forum thread for reference: https://zola.discourse.group/t/feature-request-add-support-for-avif-images-to-resize-image/538

I don't have much development time at the moment due to real life, but happy to take a crack at this at a later date if no one else has claimed it.

@BezPowell
Copy link
Contributor Author

As of image v0.23.12 there is now an ImageOutputFormat::Avif option for using with write_to. So far though, it is only possible to encode avif images with a quality setting of 100, which results in really large files. When setting the quality becomes available, I will have another stab at adding this to zola, reusing the quality setting from jpegs.

@pawelurbanski
Copy link

Maybe this will be useful/helpful:
https://github.com/kornelski/cavif-rs

@BezPowell
Copy link
Contributor Author

Maybe this will be useful/helpful:
https://github.com/kornelski/cavif-rs

That's the very crate image-rs are using for avif encoding, seems to be a really good choice for avif support. My pr to allow creating an avif encoder with specified speed and quality has just been merged, so hopefully we'll be able to add support to Zola soon.

@pawelurbanski
Copy link

pawelurbanski commented Dec 2, 2020 via email

@skyfaller
Copy link

I was thinking about the following feature. It very likely should be filed as an idea to Kornel, the cavif-rs author. When converting files for the web, we very likely need multiple sizes. It would be useful to be able to pass a list/array of resolutions to the convert call.

I already asked for resizing to be supported, and kornel said no, you should use ImageMagick instead: kornelski/cavif-rs#7

I don't know if there is some ImageMagick equivalent written in Rust, but finding or creating such a thing with support for AVIF may be worthwhile.

@BezPowell
Copy link
Contributor Author

I was thinking about the following feature. It very likely should be filed as an idea to Kornel, the cavif-rs author. When converting files for the web, we very likely need multiple sizes. It would be useful to be able to pass a list/array of resolutions to the convert call.

I already asked for resizing to be supported, and kornel said no, you should use ImageMagick instead: kornelski/cavif-rs#7

I don't know if there is some ImageMagick equivalent written in Rust, but finding or creating such a thing with support for AVIF may be worthwhile.

As far as I am aware the resizing and encoding stages are separate in the image-rs crate. Zola's resize_image() function will load the source image, resize it, and then re-encode to whatever format you specify. On my site I'm currently doing this for images with srcsets, loading the sizes from a json file.

{% set sizes = load_data(path="templates/includes/image_sizes.json", format="json") %}
<picture class="banner">
  {#- Jpeg srcset -#}
  <source type="image/jpeg" srcset="
    {%- for size in sizes %}
      {{- resize_image(path=src, width=size.width, height=size.height) }} {{ size.width }}w
      {%- if not loop.last %}, {% endif -%}
    {% endfor -%}
    " sizes="100vw" />

  {#- Jpeg fallback -#}
  {% set fallback = sizes | last %}
  <img src="{{ resize_image(path=src, width=fallback.width, height=fallback.height) }}" width="{{ fallback.width }}" height="{{ fallback.height }}" alt="" loading="eager" />
</picture>

As soon as avif is added it should be possible to add an additional source element with a type of image/avif and setting the format on resize_image to avif. The above example is simplified from a banner image, so the alt text is empty being purely decorative and loading is set to lazy as it appears above the fold.

@pawelurbanski
Copy link

pawelurbanski commented Dec 2, 2020 via email

@BezPowell
Copy link
Contributor Author

Keeping in mind what I cited above we should keep in mind that avif compression is quite demanding and takes much more time than resizing a jpg file or encoding to webp. That is why I was thinking if it would be possible to encode the original image and then resize it to different dimensions from that encoded source.

I'm not sure that would be possible?

As avif, jpeg and png etc are just ways of compressing the raw bitmap data, the image needs to be decoded back to raw data before it can be resized. Any transforms are then made upon the uncompressed image and would need to be re-encoded back to avif before saving. If you took a source image and resized it to 3 different sizes, each one of those new images would have to be encoded separately.

I could be totally wrong on this, as I know fliff had a similar feature where it was encoded in such a way that each slice of the image could be used to construct a smaller variant, but I don't think avif supports any form of progressive encoding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants