Closed ascorbic closed 2 years ago
Hi @ascorbic. I think the limitation is that we cannot resize webp animated output. (context https://github.com/unjs/ipx/issues/35 and https://github.com/lovell/sharp/issues/2275). So usage should be with caution.
Ooh, that makes sense. Hmm. I guess I'll need to work out a way to pass the animated
modifier through in the next/image generated URL
...though thinking about it, if we can't resize them, then there's not much point using next/image
Indeed. What do you think about supporting a no-op modifier that returns source image? (can be auto enabled for .gif
for example) Basically using ipx as a raw proxy in this situations so you don't need to duplicate logic.
Yes, we do that for svg and gif but it could be a useful addition. I'm also going to think of a syntax that can be used in next/image source URLs that will allow modifiers to be passed-through
If animated
is passed as a modifier, would it make sense to disable resizing as it breaks animation?
That would be a nice feature to avoid the wrong usage of the experimental animated
flag! We need to disable s
, w
and h
Tests:
Hello, if you hadn't seen we're currently working on both improving animated image resizing and adding GIF write support to sharp.
@lovell That's great! Will GIF write support be in the precompiled binaries?
@ascorbic Yes, via https://github.com/dloebl/cgif
That's good news! What sort of timeline is there for these two?
If you hadn't already seen, support for resizing and cropping animated GIF and WebP images was added in sharp v0.30.0.
https://sharp.pixelplumbing.com/changelog
const data = await sharp('in.gif', { animated: true })
.resize({ width: 128, height: 128 })
.toBuffer()
Let's enable animated by default then! @lovell I've enabled it only for gif
extensions for now. Is there any reason to not always pass animated: true
when optimizing images?
When returning image metadata after Sharp has processed an animated gif, I'm getting the entire 'toilet paper roll' height instead of the individual height of the pages.
Sharp(SomeGIf, { animated: true })
.webp({ quality: 80 })
.toBuffer((err, buf, info) => {
if (err) {
return reject(err);
}
return resolve({
buffer: buf,
width: info.width,
height: info.height // This is height * pages
});
});
@lovell Is there any way to get the number of pages in a gif, or the individual page height, after it is converted to a Buffer from within the callback?
Solved my issue with the following.
var pageHeight = false;
const image = Sharp(reducedImage, { animated: animated });
image
.metadata()
.then(function(metadata){
pageHeight = metadata.pageHeight ? metadata.pageHeight : metadata.height;
return image.webp({ quality: 80 })
.toBuffer((err, buf, info) => {
if (err) {
return reject(err);
}
return resolve({
sharp: buf,
width: info.width,
height: pageHeight
});
});
});
Thanks for the notice @tgcallaway. Are you also facing the same problem with IPX? (FYI we use image-meta but mainly to find mime type.)
Is there any reason to not always pass animated: true when optimizing images?
@pi0 Always passing animated: true
looks like the right approach for the scenarios ipx supports.
Is there any way to get the number of pages in a gif, or the individual page height, after it is converted to a Buffer from within the callback?
@tgcallaway Not directly at the moment. Adding pageHeight
to the info
object in the response would make a good improvement - please feel free to open an enhancement issue for this.
Currently, if you want animated output you need to specifically choose it. It would be good if animated webp input images could automatically generate animated output. I'm not sure what the overhead would be of just passing
animated
to the sharp constructor every time.