preface
Recently I was uploading pictures in the background of my blog, and suddenly I found a problem with cropping images when uploading GIF images. There is no way to crop the GIF image for the specified area, or crop the specified area to generate a new GIF of the specified size. I wanted to find a clipping library to put directly, but after searching for a long time, I couldn’t find a library that could crop giFs and then generate the clipping area, so I did it myself.
explore
If you’re just cropping the first frame on a Gif, there’s a plugin for that. I used React-Cropper for cropping. But the plugin can’t crop a GIF to generate another GIF.
What I want is something like this
The original image
Cropped GIF
Then I went to look up how to achieve the cutting of GIF images to GIF images. Although I did not find the corresponding plug-in, I found two open source libraries.
- Libgif-js parses giFs to generate Canvas
- GIF. Js converts canvas into GIF images
I found that the combination of these two functions can not achieve the effect I want.
Upload GIF => Generate the corresponding image on Canvas by parsing each frame of GIF => Canvas into GIF
implementation
Libgif-js implementation process
Libgif-js is an implementation that makes a request to the GIF path, parses the requested GIF data to generate a GIF instance (including the animation of each frame, as well as basic data such as the size), and then generates the corresponding canvas from the GIF instance
GIF. Js implementation process
Generate the final GIF by collecting the changes of each frame converted from libgif-js to the canvas.
GIF conversion to Canvas implementation process
Download the libgif-js js file from the libgif-js project. Since this library does not upload NPM, you will need to download it from the project. Libgif-js encapsulates operations on HTML nodes and cannot be used directly, because I uploaded the File and obtained the File object, so I need to modify the File partially
- The first thing you should receive is a
url
Path, you can takeThe File File
throughURL.createObjectURL(file)
Convert intourl
Let it happenXMLHttpRequest
The request. You can also send it directlygif
The link. - Then you need to pass the clipped range. The cropped range size needs to be proportional to the size of the original GIF
- Get rid of
libgif-js
File inside do not need the code, just need each frame of the image set and size on the line
Canvas conversion to GIF implementation process
Listen for each frame change that the GIF draws to the canvas, and then gif.js collects the canvas change of each frame and generates a new GIF
The GifToCanvas instance is a modification of the libgif-js wrapper, which triggers the GIF to canvas drawing by calling init
const gifToCanvas = new GifToCanvas(url, {
targetOffset: {
dx: cropBoxData.left - canvasData.left,
dy: cropBoxData.top - canvasData.top,
width: canvasData.width,
height: canvasData.height,
sWidth: cropBoxData.width,
sHeight: cropBoxData.height
}
})
// Start GIF to canvas
gifToCanvas.init()
// Collect each frame of canvas drawn by GifToCanvas through gif.js library, and finally generate GIF Blob source.
const gif = new GIF({
workers: 2.quality: 10.workerScript: '/static/js/gif.worker.js'
})
const addFrame = (canvas: HTMLCanvasElement, delay: number) = > {
gif.addFrame(canvas, { copy: true, delay })
}
// Listen to each frame change, collect each frame change
gifToCanvas.on('progress'.(canvas, delay) = > {
addFrame(canvas, delay)
})
// When the animation is finished, execute GIF. Render
gifToCanvas.on('finished'.(canvas, delay) = > {
addFrame(canvas, delay)
gif.render()
})
// After canvas generates GIF, export blob and generate new file
gif.on('finished'.(blob) = > {
const newFile = new File([blob], 'new.gif', { type: blob.type })
// Upload a new GIF file
const formDate = new FormData()
formDate.append('file', newFile)
...
})
Copy the code
This generates a cropped GIF file.
The resources
- libgif-js
- gif.js
This project complete code: GitHub repository
Online effect demonstration
Blog Post
conclusion
This project does not make too many complicated Settings, just meet the function of cropping GIF, because I only need to crop GIF to a specified size, so there are not too many customized functions
Personal blog source this project also launched the function source project | blog address
I created a new group to learn from each other, no matter you are preparing for the pit, or halfway into the students, I hope we can share and exchange together. QQ group: 810018802, click join
QQ group | The public, |
---|---|
Front end clutter |
Wax gourd random |