Vue上传图片压缩的问题
Posted jessie-xian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue上传图片压缩的问题相关的知识,希望对你有一定的参考价值。
上传图片太大,需要前台进行图片压缩
上传图片大于100* 1024 的用canvas 来压缩来解决
然后ios拍照上传会有图片旋转的问题,然后用了github 上的exif.js很好的插件,项目里面npm install exif-js --save 安装,
然后import一下就可以使用了
<div class="operate">
<span class="btn" @click="sendMsg" v-if="isSend&&isCanSend">btndesc</span>
<span class="btn" v-if="isSend&&!isCanSend">btndesc</span>
<label class="choosepic" v-if="!isSend&&!isCanUpload"></label>
<label class="choosepic" for="uploadcolor" v-if="!isSend&&isCanUpload"></label>
<input class="fileupload" type="file" accept="image/*" id="uploadcolor" @change="upload">
</div>
js
import Exif from 'exif-js'
export default
data ()
return
headerImage:'',picValue:''
,
mounted ()
,
methods:
upload (e)
let _this = this;
console.log('change----------->',e);
_this.resulting = [];
let files = e.target.files || e.dataTransfer.files;
// let length = files.length;
let timer = setTimeout(()=>
_this.$loading.show(
text: '发送中'
)
clearTimeout(timer);
,500);
_this.singleUpload(files[0],0,1);
_this.isCanUpload = false;
e.target.value = null;
,
singleUpload(files,i,length)
this.files = files;
this.name = this.files.name;
this.picValue = files;
this.imgPreview(this.picValue,i,length);
console.log(this.picValue);
,
imgPreview (file,i,length)
let self = this;
let Orientation;
// this.$emit('dealupload');
//去获取拍照时的信息,解决拍出来的照片旋转问题
EXIF.getData(file, function()
Orientation = EXIF.getTag(this, 'Orientation');
);
// 看支持不支持FileReader
if (!file || !window.FileReader)
self.$loading.hide();
return;
if (sAser.storage('deviceOS')==2) //安卓,sAser.storage('deviceOS')==2
self.checkHash(file,i,length);
else //ios sAser.storage('deviceOS')==1
if (/^image/.test(file.type))
// 创建一个reader
let reader = new FileReader();
// 将图片2将转成 base64 格式
reader.readAsDataURL(file);
// 读取成功后的回调
reader.onload = function ()
let result = this.result;
let img = new Image();
img.src = result;
img.onload = function ()
let data = self.compressImage(img,Orientation,file);
self.headerImage = data;
let fileCompress = self.convertBase64UrlToBlob(data);
self.checkHash(fileCompress,i,length);
,
rotateImg (img, direction, canvas, lastRotate)
//最小与最大旋转方向,图片旋转4次后回到原方向
const min_step = 0;
const max_step = 3;
if (img == null)return;
//img的高度和宽度不能在img元素隐藏后获取,否则会出错
let height = 0;
let width = 0;
if(lastRotate == true)
height = canvas.height;
width = canvas.width;
else
height = img.height;
width = img.width;
let step = 2;
if (step == null)
step = min_step;
if (direction == 'right')
step++;
//旋转到原位置,即超过最大值
step > max_step && (step = min_step);
else
step--;
step < min_step && (step = max_step);
//旋转角度以弧度值为参数
let degree = step * 90 * Math.PI / 180;
let ctx = canvas.getContext('2d');
switch (step)
case 0:
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height, width, height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height, width, height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0, width, height);
break;
,
//图片压缩
compressImage(img, Orientation,file)
let size = file.size;
let initSize = img.src.length;
let maxWidth = 1600;
let w = img.width;
let h = img.height;
console.log('原始 宽度:' + w + ",高度:" + h);
if(w > maxWidth)
//如果图片宽度大于1600px,则将图片进行等比缩放
let hRatio = maxWidth / w;
w = maxWidth;
h = h * hRatio;
console.log('高度缩放比例:' + hRatio +'缩放后 宽度:' + w + ",高度:" + h);
//创建一个image对象,给canvas绘制使用
let cvs = document.createElement('canvas');
cvs.width = w;
cvs.height = h;
let ctx = cvs.getContext('2d');
// this.getToast("旋转:" + Orientation, "20em", "22em");
//修复ios上传图片的时候 被旋转的问题
if(Orientation != "" && Orientation != 1)
switch(Orientation)
case 6://需要顺时针(向左)90度旋转
// ctx.rotate(Math.PI / 2);
// ctx.drawImage(img, 0, -h, w, h);
//上面的方式处理有问题,使用rotateImg方法。其他不能使用rotateImg方法,会有问题
this.rotateImg(img,'left',cvs, true);
break;
case 8://需要逆时针(向右)90度旋转
ctx.rotate(3 * Math.PI / 2);
ctx.drawImage(img, -w, 0, w, h);
break;
case 3://需要180度旋转
ctx.rotate(Math.PI);
ctx.drawImage(img, -w, -h, w, h);
break;
default:
ctx.drawImage(img, 0, 0, w, h);
console.log('特殊情況1111111111==========================>',ctx);
break;
else
console.log('特殊情況2222222222222==========================>',ctx);
ctx.drawImage(img, 0, 0, w, h);
//进行最小压缩
let rate = 0.3;
if (size<1048576)
rate = 1;
console.log('==============fileing===============>',file.size,rate);
let ndata = cvs.toDataURL('image/jpeg', 0.3);
console.log('压缩后内容:' + ndata);
console.log('压缩前:' + initSize);
console.log('压缩后:' + ndata.length);
console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");
return ndata;
,
convertBase64UrlToBlob(urlData)
//将以base64的图片url数据转换为Blob
var arr = urlData.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 Blob([u8arr], type: mime);
,
calcHash(file)
return sha1File(file);
,
postImg (file,i,length)
//这里写接口
let _this = this;
let name = _this.name;
let data = ;
// this.$emit('uploading');
// let files = this.files;
let files = file;
let param = new FormData(); //创建form对象
if(files!='')
param.append('file', files,files.name); //单个图片 ,多个用循环 append 添加
else
// this.$message.error('请添加图片');
// param.append('param', JSON.stringify(data));//添加form表单中其他数据
let config =
headers:'Content-Type':'multipart/form-data'
; //添加请求头
this.$http.post(_this.ajaxUrl,param,config)
.then(response=>
//上传成功后,检查上传后的图片是否有效
console.log('返回结果',response);
_this.uploadState(response,i,length);
).catch(err=>
_this.uploadFail();
console.log('接口失败返回结果',err);
)
,
uploadFail()
//发送图片过程中出现失败的处理
let _this = this;
_this.isCanUpload = true;
_this.$loading.hide();
,
原文:https://www.cnblogs.com/yf-html/p/9791339.html
以上是关于Vue上传图片压缩的问题的主要内容,如果未能解决你的问题,请参考以下文章