图片gzip压缩
gzip.js
/**
* 使用canvas压缩图片
*/
/**
* 将base64数据装换成file对象
* @param dataurl base64数据
* @param filename file对象文件名
* @returns {File}
*/
export function base64ToFile(dataurl, filename) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr =atob(arr[1]), n = bstr.length, u8arr =new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type:mime});
}
/**
*
* @param files 上传file对象
* @param transSize 压缩后文件的大小
* @param ext 压缩后文件扩展名
* @returns {Promise<any>}
*/
export function gzipPic(files, transSize, ext) {
// 将file对象转换成blob对象供img标签使用
var url = window.URL.createObjectURL(files)
var file = files
var img = new Image()
img.src = url
// 返回Promise对异步生成的新的file对象进行处理
return new Promise((resolve, reject) => {
img.onload =function(){
var w = this.width
var h = this.height
var max = w >= h ? w : h
var finalW,finalH
if (max <= transSize) {
finalW = w
finalH = h
} else {
var rate = w/h
var scale = transSize / max
if (w >= h) {
finalW = w * scale
finalH = finalW / rate
} else {
finalH = h * scale
finalW = finalH * rate
}
}
var canvas = document.createElement('canvas')
canvas.width = finalW
canvas.height = finalH
var cxt = canvas.getContext('2d')
//cxt.rect(0,0,finalW,finalH)
cxt.drawImage(img,0,0,finalW,finalH)
var base64 = canvas.toDataURL(ext || 'image/jpeg', 1)
var newFile = base64ToFile(base64, file.name)
resolve(newFile)
}
})
}
使用:
//html结构
<input @change="phone($event)" type="file" capture="camera" />
phone(e) {
let fs = e.target.files[0];
//源文件大于3M压缩
if (e.target.files[0].size > 3 * 1024 * 1024) {
fs = await gzipPic(e.target.files[0], 256);
if (fs.size > 3 * 1024 * 1024) {
//压缩后还大于3M的逻辑
}
}else{
//源文件小于3M正常处理
}
}
使用input上传源文件
upload.js
import { gzipPic } from './gzip'
export function uploadFile({ file, onUploadProgress, url }) {
url = url || '/snsV2/uploadPic.php'
let xhr = null
if (window.XMLHttpRequest) {
// webkit
xhr = new XMLHttpRequest()
} else {
// IE
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
xhr.open('POST', url , true)
return new Promise((resolve, reject) => {
xhr.onreadystatechange = function () {
//后端接受完毕
if(xhr.readyState == 4){
resolve(xhr.responseText)
}
}
xhr.send(file)
})
}
/**
* 文件上传处理
* @param files 文件对象
* @param isZip 是否压缩 boolean
* @param success 上传成功后处理函数
* @param transSize 压缩后文件的大小
* @param ext 压缩后文件的后缀
* @param onUploadProgress 文件上传进度处理
* @param url 上传的url
* @param fileName 控件名称
* @returns {Promise<void>}
* 方法默认接口只传一个参数(参数名默认是file)
*/
export async function handleFile({ files, isZip, success, transSize, ext, onUploadProgress, url, fileName}) {
let file = fileName || 'file'
for (let i = 0;i < files.length; ++i){
let formData = new FormData()
if (isZip) {
let res = await gzipPic(files[i], transSize, ext)
formData.append(file, res)
} else {
formData.append(file, files[i])
}
uploadFile({
file: formData,
onUploadProgress,
url
}).then((res) => {
success && success(res)
})
formData.delete(file)
}
}
使用:
<input @change="handleAddImg($event)" type="file" capture="camera" />
方法一:用handleFile方法上传图片(只能上传一个参数)
// 上传图片(用)
handleAddImg(e) {
if (e.target.value) {
let files = e.target.files;
handleFile({
files,
isZip: true,
transSize: 1500,
success: function(response) {
let res = JSON.parse(response);
if (res.code === 20000) {
// 上传成功逻辑:图片地址res.data.url
} else {
//上传失败逻辑
}
}
});
}
},
方法二:用uploadFile方法上传图片(可上传多个参数)
handleAddImg(e){
if(e.targe.value){
let fs = e.target.files[0];
let formData = new FormData();
formData.append('file', fs);
formData.append('token', 'xxxx');
formData.append('type', 'ooo');
uploadFile({ file: formData, url: '/v2/realname/abroad/uploadImg.php' })
.then((info) => {
let res = JSON.parse(info);
if (res.code == 20000) {
res = res.data;
//上传成功逻辑
} else {
//上传失败逻辑
}
})
.catch((err) => {});
}
}