Create gif from Facebook sticker

Tram Ho

Even though the Facebook and Messenger apps are bad, they have really cute stickers. But you try to download, there is no way to download as a gif file file. Anyway, it appears already, there is no way to download. Try inspect element, we will see it appears as a spritesheet set to background-image and use background-position to change the frame.

animate-spritesheet

This is the spritesheet.

tonton-inspect

So now we will do like this:

  1. Get the frames from spritesheet
  2. Merge into gif file

Split frames from spritesheet

Looking at the spritesheet up there, you can see that it has 8 frames, each size is 288px * 288px . You can manually cut it out by any app. Or we will write a script to cut out. We will use the Canvas API to render frames from spritesheet.

Suppose we have a spritesheet loaded on a page like this

To cut out each frame, we will create a canvas of size 288px * 288px and render the corresponding part on the sprite sheet onto that canvas. For example, to cut the first frame, we do like this

You should see the first frame like this

first_frame

The second and third parameters of drawImage will be the position of the frame on the spritesheet. Document details here .

To cut all the frames, we make a loop like this

You will notice that we have an extra empty frame, so we have to add a check to see if the frame we just cut has data before adding to the array frames . Simply check whether all its pixels have data or not.

Merge frames into GIF image

If I have frames then I can stitch them together. I will use the gif.js package to create gif images. Creating images from frames is as simple as this.

Just add the frames and the delay between frames then render. To make it easy to calculate, we use the concept of frame rate, often the Facebook stickers I see have frame rate from 8-12 fps. The result will be raw data so we use URL.createObjectURL to create a temporary URL. Our result is like this.

tonton-black

It’s okay, except for the black background ra. This is because our image is partially transparent, so the gif is rendered. If you add options transparent to gif.js like this

Then we get results like this.

tonton-black

There is a transparent background but the contours are not very good. This is due to the limitation of the GIF format. Normally, with a transparent image such as PNG, the transition from the image to the transparent place will be a lot of pixels with reduced transparency like this to make the border of the image smooth.

tonton-edge

However, with the GIF format, each px can only be colored or completely transparent, not half transparent like PNG. So the contour looks like a low-quality serrated pattern. So a gif that has a transparent background usually has a small white border (or something that overlaps with the background where people plan to put the gif on) to make the border look smoother. For simplicity, I will give the white background as well.

Remember to color before drawImage or it will overwrite the image. Our result is like this.

tontontonton

This is the whole code if you want to play with it.

 

Link codepen if the embed doesn’t load  https://codepen.io/thphuong/pen/qBOyRaz

Bonus

Regarding how Facebook works, why use a spritesheet without using a GIF image. Doing this also has some benefits.

  • Better photos, GIF images have 256 colors instead of 16 million colors like PNG.
  • No problem with transparent as I mentioned above anymore.
  • No need to be copied.

But there must also be some that are not beneficial

  • No resizing. Because using background-image and background-position , the size of the sticker is fixed, to change spritesheet to change.
  • Running RAM with CPU.
Share the news now

Source : Viblo