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

Sharp removes GIF animation #3625

Closed
3 tasks done
Spedwards opened this issue Apr 14, 2023 · 3 comments
Closed
3 tasks done

Sharp removes GIF animation #3625

Spedwards opened this issue Apr 14, 2023 · 3 comments
Labels

Comments

@Spedwards
Copy link

Possible bug

When passing a path to an animated GIF and using either toFile(..) or toBuffer(), the returned GIF has no animation. The toBuffer() method is important to me as I need it to upload images to an image host.

Is this a possible bug in a feature of sharp, unrelated to installation?

  • Running npm install sharp completes without error.
  • Running node -e "require('sharp')" completes without error.

If you cannot confirm both of these, please open an installation issue instead.

Are you using the latest version of sharp?

  • I am using the latest version of sharp as reported by npm view sharp dist-tags.latest.

If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.

If you are using another package which depends on a version of sharp that is not the latest, please open an issue against that package instead.

What is the output of running npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp?

  System:
    OS: Windows 10 10.0.19045
    CPU: (8) x64 Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz
    Memory: 9.15 GB / 31.92 GB
  Binaries:
    Node: 16.15.0 - ~\.nvm\versions\node\v16.15.0\bin\node.EXE
    Yarn: 1.22.4 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 8.5.5 - ~\.nvm\versions\node\v16.15.0\bin\npm.CMD
  npmPackages:
    sharp: ^0.32.0 => 0.32.0

What are the steps to reproduce?

await sharp(pathToAnimatedGif).gif().toFile('sample.gif')

The file, sample.gif, will not be animated. This also applies to the toBuffer() method but I'm unsure how best to showcase that.

What is the expected behaviour?

The returned image/buffer should include the animation data. According to the AnimationOptions interface, loop should default to 0 (infinite). I'm unsure if that's even the issue as 1 would at least show the other frames. All I'm getting is a static image.

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem

const sharp = require('sharp')

const pathToAnimatedGif = 'some_animated_gif.gif'
sharp(pathToAnimatedGif).gif().toFile('sample.gif')

Please provide sample image(s) that help explain this problem

some_animated_gif.zip or imgur link

@Spedwards
Copy link
Author

Hmm... I ended up doing some exploring after posting this to see if I could find another library to handles GIFs in the meantime, but something referenced sharp and included a second argument to the sharp constructor, { animated: true }. That resolved the animation issue however it appears to more than double the file size of that example image I've included. Is there anyway around that?

@lovell lovell added question and removed triage labels Apr 15, 2023
@lovell
Copy link
Owner

lovell commented Apr 21, 2023

It looks like the some_animated_gif.gif file has been highly optimised via a tool such as gifsicle, including some clever use of different transparent palette indexes per frame:

gifsicle --info some_animated_gif.gif 
* some_animated_gif.gif 36 images
  logical screen 700x700
  global color table [256]
  background 0
  loop forever
  + image #0 700x700
    disposal asis delay 0.04s
  + image #1 700x693 at 0,7 transparent 153
    disposal asis delay 0.04s
  + image #2 700x693 at 0,7 transparent 150
    disposal asis delay 0.04s
  + image #3 700x625 at 0,75 transparent 151
    disposal asis delay 0.04s
  + image #4 686x585 at 14,115 transparent 146
    disposal asis delay 0.04s
...

Please see #3610 for a previous related question and a possible suggestion to create a wrapper that brute forces its way through various configuration options to find the smallest output, as this is what GIF optimisation tools do.

@lovell
Copy link
Owner

lovell commented Apr 27, 2023

I hope this information helped. Please feel free to re-open with more details if further assistance is required.

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

No branches or pull requests

2 participants