node.js判断在线图片链接是否是webp,并将其转格式后上传
1、通过设置请求头里的Range参数,只请求指定的字节数,然后判断对应图片格式的字节
const axios = require('axios');
function checkWebPFormat(url) {
return new Promise(async (resolve, reject) => {
try {
// 使用 axios 获取图片数据,设置 responseType 为 'arraybuffer'
const response = await axios({
method: 'get',
url,
responseType: 'arraybuffer',
headers: {
'Range': 'bytes=0-100',
'Accept-Ranges': 'bytes',
// 'Content-Type': 'application/octet-stream'
}
});
console.log('checkWebPFormat::', url)
// 将响应数据转换为 Buffer
// const imageBuffer = Buffer.from(response.data);
const imageBuffer = response.data.toString('utf8');
// console.log('String utf8::', imageBuffer)
// 判断是否是 WebP 格式
const isWebP = imageBuffer.indexOf('RIFF') === 0 && imageBuffer.indexOf('WEBP') !== -1;
console.log(`图片是否是 WebP 格式? ${isWebP}`);
resolve(isWebP)
} catch (error) {
console.error('Error:', error.message);
reject()
}
})
}
2、通过sharp第三方库将webp图片数据转成png格式
const sharp = require('sharp');
function convertWebPToPng(url) {
return new Promise(async (resolve, reject) => {
try {
// 使用 axios 获取图片数据,设置 responseType 为 'arraybuffer'
const response = await axios({
method: 'get',
url,
responseType: 'arraybuffer',
headers: {
// 'Range': 'bytes=0-100',
// 'Accept-Ranges': 'bytes',
// 'Content-Type': 'application/octet-stream'
}
});
// 2. 使用 sharp 将 WebP 转换为 PNG
const pngBuffer = await sharp(response.data)
.png() // 设置输出格式为 PNG
.toBuffer();
resolve(pngBuffer)
} catch (error) {
console.error('Error:', error.message);
reject()
}
})
}
3、把获取到的buffer数据转成file数据
拿到file数据后就可以通过上传接口把数据上传上去
function convertBufferToFile(buffer, fileName) {
// 将 Buffer 转换为 Blob
const blob = new Blob([buffer], { type: 'image/png' });
let file = new File([blob], fileName+'.png')
return file
}
4、blob、File、base64格式之间互相转换
Blob是一种二进制数据类型,通常表示二进制文件、图片、音频或视频等媒体资源
File 对象通常是用户在网页中的一个 元素上传文件返回的 FileList 对象,或者是拖放操作返回的 DataTransfer 对象,也可以在浏览器中的控制台中自己创建
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。编码规则:把3个字节变成4个字节;每76个字符加一个换行符;最后的结束符也要处理
blob 转 File
function blobToFile(blob, fileName) {
const file = new File([blob], fileName, { type: blob.type })
return file
}
blobToFile(blob, 'xx.png')
File 转 blob
function fileToBlob(data) {
return new Promise((resolve, reject) => {
const fileReader = new FileReader()
fileReader.onload = (e) => {
const blob = new Blob([e.target.result], { type: data.type })
resolve(blob)
}
fileReader.readAsDataURL(data)
fileReader.onerror = () => {
reject(new Error('文件流异常'))
}
})
}
await fileToBlob(file)
blob 转 base64
function blobToBase64(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(blob)
reader.onload = (e) => {
resolve(e.target.result)
}
})
}
await blobToBase64(blob)
base64 转 blob
function base64ToBlob(base64) {
let arr = base64.split(',')
let type = arr[0].match(/:(.*?);/)[1]
let bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: type })
}
base64ToBlob(base64)
File 转 base64
function fileToBase64 (data) {
return new Promise((resolve, reject) => {
const fileReader = new FileReader()
fileReader.onload = (e) => {
resolve(e.target.result)
}
fileReader.readAsDataURL(data)
fileReader.onerror = () => {
reject(new Error('文件流异常'))
}
})
}
await fileToBase64(file)
base64 转 File
function base64ToFile(base64, filename) {
const arr = base64.split(',')
const type = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: type })
}
base64ToFile(base64, 'xx.png')