一、判断是否为GIF图片类型
在JavaScript中,判断用户上传的文件是否为GIF文件类型时,通常可以通过检查文件的type属性或文件的拓展名来判断,但是由于文件拓展名可以轻易被用户修改,type属性是由浏览器根据文件拓展名猜测得出的,因此这种判断方式并不总是准确的。
为了更准确的判断文件类型,需要读取文件的头部字节,并检查这些字节是否符合GIF文件的规范。
要检查文件头部字节以确定文件是否为GIF格式,可以使用JavaScript的FileReader API来读取文件的前几个字节,并与GIF文件的魔数(Magic Number)进行比较。GIF文件的魔数是GIF87a或GIF89a,它们位于文件的前几个字节中。
// 文件输入元素
const fileInput = document.getElementById('file-input')
// 监听文件变化事件
fileInput.addEventListener('change', async fucntion(e) {
// 获取用户选择的文件
const file = e.target.files[0]
if(file) {
const isGif = await checkGifFileType(file)
if(isGif) {
// 是gif
} else {
// 不是gif
}
}
})
/**
* 检查文件类型是否是gif
*
* @param {*} file
* @returns
*/
export function checkGifFileType(file) {
// 创建一个FileReader对象
const reader = new FileReader();
// 读取文件的前几个字节
reader.readAsArrayBuffer(file.slice(0, 6)); // GIF的魔数只需要6个字节
return new Promise((resolve, reject) => {
reader.onload = function (e) {
// 将ArrayBuffer转换为Uint8Array以便读取字节
const arrayBuffer = e.target.result;
const uint8Array = new Uint8Array(arrayBuffer);
// GIF文件的魔数可以是'GIF87a'或'GIF89a',转换为ASCII码分别为[71, 73, 70, 56, 55, 97]或[71, 73, 70, 56, 57, 97]
// 检查文件的前6个字节是否匹配GIF的魔数
const gif87a = [71, 73, 70, 56, 55, 97];
const gif89a = [71, 73, 70, 56, 57, 97];
if (
(uint8Array[0] === gif87a[0] &&
uint8Array[1] === gif87a[1] &&
uint8Array[2] === gif87a[2] &&
uint8Array[3] === gif87a[3] &&
uint8Array[4] === gif87a[4] &&
uint8Array[5] === gif87a[5]) ||
(uint8Array[0] === gif89a[0] &&
uint8Array[1] === gif89a[1] &&
uint8Array[2] === gif89a[2] &&
uint8Array[3] === gif89a[3] &&
uint8Array[4] === gif89a[4] &&
uint8Array[5] === gif89a[5])
) {
resolve(true); // 是GIF文件
} else {
resolve(false); // 不是GIF文件
}
};
reader.onerror = function (error) {
reject(error);
};
});
}
二、解析GIF,并在canvas上播放
GIF本质上和视频一样,都是一帧一帧的图片拼合而成,所以,在canvas上播放GIF功能实现的要点,就是获取具体某一帧的资源。
- 使用ImageDecode