I'm trying to convert animate image in .webp to .apng ; i've tried the following:
from PIL import Image, ImageSequence
from apng import APNG
im = Image.open('/content/animate_w.webp')
#im.save('/content/animate_w.apng', 'apng', save_all = True, optimize = True, background=0) # not work
im.save('/content/animate_w.png', 'png', save_all = True, optimize = True, background=0)
im = Image.open('/content/animate_w.png')
i = 0
for frame in ImageSequence.Iterator(im):
ex_command = f'frame_{i} = frame'
exec(ex_command)
i += 1
# not really sure what's next
files = [
("frame_1.png", 100),
("frame_2.png", 200),
("frame_3.png", 300)
]
im = APNG()
for file, delay in files:
im.append_file(file, delay=delay)
im.save("result.apng")
the individually saving frame part does not work and i'm not sure how to proceed next. Any idea?
You have the correct direction, you just need to add steps to extract the frames from the webp file.
I hope the following code can add more ideas on how to achieve it.
I am using webptools to extract the frames
from webptools import webpmux_getframe
from PIL import Image, ImageSequence
from apng import APNG
# Load the webp file
# Downloaded from https://pullzone1-corydowdywebdesi.netdna-ssl.com/assets/blog/apngwebp/squirrel.q70.m6.mixed.webp
im = Image.open('squirrel.q70.m6.mixed.webp')
# Get the number of frames
num_of_frame = 0
for frame in ImageSequence.Iterator(im):
ex_command = f'frame_{num_of_frame} = frame'
exec(ex_command)
num_of_frame += 1
# Extract the frames
list_of_files = []
for i in range(num_of_frame):
webpmux_getframe(input_image='squirrel.q70.m6.mixed.webp', output_image=f'output_frame{i}.png', frame_number=i)
list_of_files.append(f'output_frame{i}.png')
# Save to APNG
im = APNG()
for filename in list_of_files:
im.append_file(filename)
im.save('result.apng')
# Load frame from APNG file
im = APNG.open('result.apng')
for i, (png, control) in enumerate(im.frames):
png.save(f'apng_frame_{i}.png')
Another solution without using webptools is using WebPimageFile from PIL
from PIL import WebPImagePlugin
from apng import APNG
# Load webp and extract the frames
imwebp = WebPImagePlugin.WebPImageFile('squirrel.q70.m6.mixed.webp')
nframes = 0
list_of_files = []
while imwebp:
imwebp.seek(nframes)
imwebp.save(f'output_frame{nframes}.png', 'PNG')
list_of_files.append(f'output_frame{nframes}.png')
nframes += 1
try:
imwebp.seek(nframes)
except EOFError:
break
# Save to APNG
im = APNG()
for filename in list_of_files:
im.append_file(filename)
im.save('result.apng')
# Load frame from APNG file
im = APNG.open('result.apng')
for i, (png, control) in enumerate(im.frames):
png.save(f'apng_frame_{i}.png')