最近在博客後臺上傳圖片的時候,忽然發現上傳gif圖片的時候裁剪圖片有問題。既無法裁剪gif指定區域的圖片,又無法裁剪指定區域生成一個新的指定大小的gif圖。原本想直接去找個裁剪的庫直接放上去的,可是找了半天也沒找到可以裁剪gif而後生成裁剪區域的gif的庫,因而就本身動手了。html
若是隻是單純的在Gif上裁剪第一幀圖片,卻是有插件能實現,我用的就是react-cropper來進行圖片裁剪的。可是這個插件無法裁剪GIF生成另外一個GIF圖。前端
我要的效果是下面這樣的效果react
原圖git
裁剪後的gif圖github
而後就去查了下如何實現gif圖到gif圖的裁剪,雖然沒有找到對應的插件,可是找到了兩個開源的庫。typescript
發現這兩個功能一組合不就能夠實現我要的那個效果了麼。npm
上傳GIF => 經過解析GIF每一幀在Canvas上生成對應的圖像 => canvas轉成GIFcanvas
libgif-js
是經過實現對gif路徑發起一個請求,而後經過解析請求回來的gif數據來生成GIF實例(包括每一幀的動畫,以及大小之類的基礎數據),而後經過GIF實例生成對應的canvas
markdown
經過收集libgif-js
轉換到canvas上面的每一幀的變化,來生成最終的GIF
。app
首先到libgif-js這個項目中下載對應的js文件,由於這個庫並無上傳npm,因此須要本身去項目中下載。 libgif-js
他這個封裝的是對HTML
節點的操做,無法直接去用,由於我是上傳文件,獲取的File
對象,因此須要對這個文件進行部分修改
url
路徑,能夠把File文件
經過URL.createObjectURL(file)
轉成成url
,讓其進行XMLHttpRequest
請求。 也能夠直接傳gif
的連接。libgif-js
文件裏面不須要的代碼,只須要其中每一幀的圖像集合跟尺寸大小就行監聽gif繪製到canvas上的每一幀變化,而後gif.js
收集每一幀的canvas變化,最後生成新的gif
// 導出gif實例, GifToCanvas實例是對libgif-js封裝的修改,經過調用init方法,觸發gif到canvas的繪製
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
}
})
// 啓動gif轉canvas
gifToCanvas.init()
// 經過 gif.js 庫來收集由 GifToCanvas繪製出來的canvas裏面的每一幀,最後生成gif的Blob源。
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 })
}
// 監聽每一幀的變化,收集每一幀的變化
gifToCanvas.on('progress', (canvas, delay) => {
addFrame(canvas, delay)
})
// 動畫執行完畢,執行gif.render
gifToCanvas.on('finished', (canvas, delay) => {
addFrame(canvas, delay)
gif.render()
})
// canvas生成gif完畢,導出blob, 生成新的文件
gif.on('finished', (blob) => {
const newFile = new File([blob], 'new.gif', { type: blob.type })
// 上傳新的gif文件
const formDate = new FormData()
formDate.append('file', newFile)
...
})
複製代碼
這樣就生成了一個裁剪後的gif文件。
參考資源
本項目完整的代碼:GitHub 倉庫
這個項目也沒有作太多複雜的設置,知足裁剪GIF的功能就行,由於我目前只須要把gif裁剪成指定大小的gif就行,因此並無作太多特製化的功能
我的博客源碼這個項目也上線了這個功能 | 博客源碼項目地址
我本身新建立了一個相互學習的羣,不管你是準備入坑的小白,仍是半路入行的同窗,但願咱們能一塊兒分享與交流。 QQ羣:810018802, 點擊加入
QQ羣 | 公衆號 |
---|---|
前端打雜羣![]() |
冬瓜書屋![]() |