前端JS实现GIF动图分解为多帧PNG并上传
作者:工具松鼠时间:2026-10-23 12:18:15浏览:83
本文介绍如何在Web项目中利用libgif-js库将GIF动图分解为多帧PNG图片。通过创建img元素并实例化SuperGif类获取每一帧的Canvas数据,再将其转换为File对象,最终实现单张图片的多帧拆分与批量上传功能,适用于头像裁剪或素材库管理等场景。
GIF分解与上传实现概述
在项目开发中,有时需要支持用户上传GIF格式的图片,并将其分解后的每一帧图片一次性展示给用户。下面直接展示相关实现代码。
要实现GIF图片的分解功能,需要依赖libgif-js这个第三方库。
第一步是引入该Git库。
引入依赖库
import SuperGif from './libgif.js'
第二步是将GIF分解为PNG图片。
GIF分解为PNG图片
const GifDecomposer = {
structureGifObject (gifFiles, cb) { // gifFiles 获取的文件对象 e.target.files[0]
const gifImg = document.createElement('img');
gifImg.setAttribute('rel:animated_src', URL.createObjectURL(gifFiles));
gifImg.setAttribute('rel:auto_play', '0');
// Modified pictures must be added to the body
document.body.appendChild(gifImg);
// Construction example
var rub = new SuperGif({ gif: gifImg });
rub.load(() => {
var img_list = [];
for (let i=1; i <= rub.get_length(); i++) {
// Traversing through each frame of a GIF instance
rub.move_to(i);
// Converting each frame of canvas into a file object
let cur_file = this.convertCanvasToImage(rub.get_canvas(), gifFiles.name.replace('.gif', '') + `-${i}`)
img_list.push({
file_name: cur_file.name,
url: URL.createObjectURL(cur_file),
file: cur_file,
})
}
cb(img_list)
});
},
dataURLtoFile (dataurl, filename) {
const arr = dataurl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
var n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type:mime});
},
convertCanvasToImage (canvas, filename) {
return this.dataURLtoFile(canvas.toDataURL('image/png'), filename);
}
}
第三步是上传分解后的每一张图片。
上传图片处理
/**
* costume upload GIF decomposer
*/
const filesImg = function (list, storage, costumeFormat, assetType, handleCostume) {
let proDataList = list.map((item, index) => {
return new Promise(function(resolve, reject) {
let reader = new FileReader();
reader.readAsArrayBuffer(item.file);
reader.onload = () => {
let data = {result: reader.result, type: item.file.type, name: item.file.name}
resolve(data);
};
reader.onerror = (error) => {reject(error)};
})
})
Promise.all(proDataList).then(res => {
res.forEach(item => {
// 上传
})
}).catch(data => {console.log(data)})
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
作者最新文章
JS表单序列化出现中文乱码怎么解决
2026-11-05 17:21:05
JS代码在线格式化工具推荐:无需安装快速美化
2026-11-05 17:17:49
WebStorm内置JS代码格式化功能怎么用
2026-11-05 10:10:47
在线JS代码格式化与混淆压缩工具推荐及使用指南
2026-11-03 20:31:53
CodePen、JSFiddle与RunJS对比:哪款在线JavaScript编辑器更好用
2026-11-03 18:52:45
