benwiley4000 / react-gif-player

📽 A GIF component that moves when YOU want it to!
https://benwiley4000.github.io/react-gif-player/
MIT License
94 stars 32 forks source link

Cross-platform help: getting first frame from GIF w/ GraphicsMagick #3

Closed benwiley4000 closed 7 years ago

benwiley4000 commented 7 years ago

People who want to use this might not know an easy way to extract the first frame from a GIF as a still image. GraphicsMagick enables this cross platform but users may need assistance installing and using it to get the first frame from an animated GIF.

We should have a new .md file (linked from README.md) with these instructions.

ETA: Three-pronged approach to solving this:

~- [ ] Recommend using gifsicle in an .md file.~ ~- [ ] Develop a separate webpack loader for importing a gif resource, generating a still image, and providing static resource links to the user.~

xRahul commented 7 years ago

can we not integrate it? or use so package to auto get the still without user going through all the hassle?

benwiley4000 commented 7 years ago

There's a Node package for GraphicsMagick but it still requires the binaries to be installed on the user's system. It also won't run in the browser. We could distribute it with this package for use as a build tool (not a bad idea necessarily) but I'm not sure we could really automate this for the user. If you know of any packages that don't require separate system package installs let me know! :smiley:

You did make me think of something though - drawing a GIF to the canvas will only draw the first frame. We can extract a png data url from the canvas. Try this (in the console on this page):

function drawGif (canvas, src) {
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');
    var img = new Image();
    img.onload = () => {
      ctx.drawImage(img, 0, 0);
      console.log(canvas.toDataURL());
    };
    img.src = src;
  }
}

var canvas = document.createElement('canvas');
document.body.appendChild(canvas);

var gif = "flip_the_frog.gif";
drawGif(canvas, gif);

The unfortunate catch is that we can't draw the gif to the canvas until it has fully loaded, and part of the whole point of this package is to display an image immediately without waiting for the network the load the gif.

That said, I would be fine with integrating such a system into the module as a backup when a gif is supplied but a still isn't. Would you be interested in working on it?

benwiley4000 commented 7 years ago

I had a typo in my code example until a moment ago - I was using a setTimeout (from something I was testing) instead of img.onload.

xRahul commented 7 years ago

I've found an alternative- http://www.lcdf.org/gifsicle/

gifsicle anim.gif '#0' > firstframe.gif

or

./node_modules/gifsicle/cli.js anim.gif '#0' > firstframe.gif

the above command extracts the frame, and it's a simple node module

benwiley4000 commented 7 years ago

Nice find!

Also, here's a package that can be used in Node instead of GraphicsMagick - get-pixels. Save to file with save-pixels.

Extracts data from image with no external native dependencies - perhaps not a huge issue since Gifsicle seems to automate its external dependencies, but this would be less likely to encounter compatibility issues.

I'm still unsure of the best way to automate this for the user ahead of compile time, though.

benwiley4000 commented 7 years ago

@xRahul I think the best path forward is threefold:

Would you like to work on either 1 or 2 (or both)?

xRahul commented 7 years ago

Sure! I think i can even work on the last one as I've used webpack a lot. Though It'll be on the weekends as I'm far too busy to give it appropriate time on weekdays

benwiley4000 commented 7 years ago

I've already jumped into writing the webpack gif loader and I'm going to push up a first pass soon (as a separate repo/module). That said, if you'd like to contribute once I've drafted it, I wouldn't mind the help!

Also, completely understood re: availability. Do you think you'll have time to work on it this weekend?

I'm excited to make this module more accessible. Thanks again for the help and feedback. :smile:

benwiley4000 commented 7 years ago

v0.2.0 addresses this issue partially (via post-load swap using canvas element).

I'm going to continue working on the webpack loader.

benwiley4000 commented 7 years ago

I got frustrated and angry at the webpack loaders/plugins documentation, and then I decided it made more sense to just develop a build tool-agnostic module which can enable streamlined still frame generation in simple fashion. I've added it to the readme here.

xRahul commented 7 years ago

sorry I wasn't able to work on this. I shifted my focus. gif-frames looks good.