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

Saving in AVIF takes a long time and weighs more than the original (animated RGBA webp) #65

Open
ViktorSky opened this issue Nov 29, 2024 · 2 comments

Comments

@ViktorSky
Copy link

python version: 3.13
OS: windows 11
Pillow version: 11.0.0

My goal when using AVIF is to take advantage of its understanding that it is better than webp, to store with a smaller size without losing quality. I was testing for various types of cases that could happen, and I found a webp that takes too long to save and also the result is much larger than the original

The webp (3.86 MiB), It looked like it was GIF, but it's WEBP, do print(im.format)

This is the code I used to convert just that webp

import time
from PIL import Image, ImageSequence
import pillow_avif

im = Image.open("input.webp")
frames = list[Image.Image]()
for frame in ImageSequence.Iterator(im):
    # I convert to P, to reduce the frame data
    frame = frame.convert("P", palette=Image.Palette.ADAPTIVE)
    frames.append(frame.copy())
s = time.time()
frames[0].save("out.avif", save_all=True, append_images=frames[1:], optimize=True)
print(time.time() - s)

It took ~112.06 seconds and the final size was 6.06 MiB

Could you explain to me what is happening here? I expected the AVIF result to be smaller, but it went up almost 100%

@fdintino
Copy link
Owner

fdintino commented Dec 3, 2024

By default, pillow-avif-plugin uses the aom codec, which can be fairly slow and inefficient without extra tuning. You probably want to use either SVT-AV1 or rav1e instead, and you'll also want to set a lower quality than the default; you can usually get away with a bit more compression with video and animation without affecting perceptual quality as much. There's also no reason to convert the frame modes like this. AVIF images are always encoded in YUV, so the file size will be the same regardless of whether the source mode is I, P, or RGB(A).

Encoding with SVT-AV1 (on a 16-core MacBook Pro M3):

im.save("out.avif", save_all=True, codec="svt", speed=4, quality=50)

I get a 1.1 MiB file in 2.2 seconds. With rav1e:

im.save("out.avif", save_all=True, codec="rav1e", speed=4, quality=50, tile_rows=1, tile_cols=2)

I get a 594 KiB file in 3.9 seconds.

I would recommend experimenting with different speed and quality settings to determine what values give you the best performance and quality trade-off for your use-case.

A side-note about the AOM codec: it is extremely configurable, but the default settings are terrible. For instance, running an encode with these settings:

im.save(
    "out.avif",
    save_all=True,
    codec="aom",
    speed=5,
    quality=50,
    advanced={
        "color:deltaq-mode": "3",
        "color:enable-qm": "1",
        "color:enable-chroma-deltaq": "1",
        "end-usage": "vbr",
    },
)

I get a 599 KiB file in 2.9 seconds. But to get it, you need to specify a bunch of codec-specific options. Hence why I generally recommend rav1e or SVT.

@ViktorSky
Copy link
Author

ViktorSky commented Dec 4, 2024

Is it possible to change the default codec to save? I see that rav1e is giving better results than the other codecs

I don't see the benefit of sacrificing quality, it is better to distribute processes with cpu or gpu, or optimize the algorithms. although I don't know if all that is already done, although I think that part already belongs to Pillow, and not to the plugin

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

2 participants