移动端图片压缩上传解决方案

时间:2021-09-30 19:59:52

最近做移动端图片上传,发现图片尤其是iPhone拍照的图片都有2M左右,但是实际上项目中用不到这么大,于是想到要用js在前台进行压缩。

解决方案如下:

网上搜了很多效果都不怎么好,这个还行:http://think2011.net/localResizeIMG/test/

使用可以参考具体文档,我是在Vue环境下,不过不影响使用,直接贴代码了:

  import cropper from 'cropper'
import imgUrl from '../assets/images/preview.png'
import api from '../fetch/api'
import VHeader from '@/components/Header.vue'
import {Toast} from 'mint-ui'
import {Indicator} from 'mint-ui'
import lr from '../fetch/lrz.bundle'
var data = {data: {}, appid: api.appid, id: ''};
var inputs = {};

export default {
components: {
VHeader
},
data() {
return {
id: '',
name: '',
coverPic: '',
iptList: {},
input: false,
image: false,
isEmpty: true,
requireList: null,
data: {data: {}, appid: api.appid, id: ''},
inputs: {},
imgSrc: '',
cropImg: imgUrl,
crop: '',
cropper: false,
ratio: '',
shape: '',
croppedCanvas: '',
base64: '',
picBlob: '',
isPureFile: true,
fileKey: ''
}
},
mounted() {
this.getData();
this.requireList = document.getElementsByClassName('required');
document.getElementById('coverPic').onload = function () {
if (document.body.scrollHeight - document.body.clientHeight > 20) {
document.body.scrollTop = document.body.scrollHeight;
}
}
},
methods: {
getData() {
let self = this;
let id = self.$route.params.id;
self.id = id;
self.$http.get(api.getColumns + '1&id=' + id + api.defaultAppid)
.then(res => {
let result = res.data.data.result[0];
self.name = result.name;
self.coverPic = result.previewPic || result.coverPic;
self.iptList = result.inputs;
self.ratio = result.inputs.picRatio || 1;
})
.catch(function (error) {
console.log('error' + error);
});
},
getObjectURL(file) {
var url = null;
if (window.createObjectURL != undefined) { // basic
url = window.createObjectURL(file);
} else if (window.URL != undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) { // webkit or chrome
url = window.webkitURL.createObjectURL(file);
}
return url;
},
setImage(e) {
let self = this;
let objUrl;
const file = e.target.files[0];
if (!file.type.includes('image/')) {
Toast('请选择图片');
return;
}
if (file.size > 1024 * 1024 * 3) {
Toast('图片不能大于3M');
return;
} else if (file.size > 1024 * 1024 * 1) {//大于1M就进行压缩
self.compress(file)
} else {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
var objUrl = e.target.result;
//self.picBlob = self.getBlob(objUrl);
$('.cropper').append('<img id="uploadImg" src="" class="uploadImgC">');
$('#uploadImg').attr('src', objUrl);
$('#uploadImg').cropper({
aspectRatio: self.ratio, //裁剪比例
viewMode: 1,
});
}
}
this.cropper = true;
},
sure() {
let self = this;
self.croppedCanvas = $('#uploadImg').cropper('getCroppedCanvas');
if (self.shape == '0') { // Round
self.croppedCanvas = this.getRoundedCanvas(self.croppedCanvas);
}
let objUrl = self.croppedCanvas.toDataURL();
self.base64 = objUrl;
self.picBlob = self.getBlob(objUrl);
console.log('blob' + self.picBlob.size / 1024 / 1024);
$('#priviewImg').attr('src', objUrl);
$('#uploadImg').cropper('clear');
$('#uploadImg').remove();
$('.cropper-container').remove();
self.cropper = false;
},
rotate() {
$('#uploadImg').cropper('rotate', 20);
},
compress(file){
let self=this;
lrz(file, {
width: 800
})
.then(function (rst) {
// 处理成功会执行
// console.log(rst);
// after.src = rst.base64;
var objUrl = rst.base64;
console.log('base64:' + objUrl.length/1024/1024+'M');
$('.cropper').append('<img id="uploadImg" src="" class="uploadImgC">');
$('#uploadImg').attr('src', objUrl);
$('#uploadImg').cropper({
aspectRatio: self.ratio, //裁剪比例
viewMode: 1,
});
})
.catch(function (err) {
})
.always(function () {
});
},
makePic() {
let self = this;
let list = [].slice.call(this.requireList), len = list.length, i = 0;
for (i in list) {
let input = list[i];
if (input.type == 'file') {
if (input.value == '') {
Toast('请先上传图片');
this.isEmpty = false;
return false;
} else {
this.isEmpty = true;
}
} else if (input.type == 'text') {
self.isPureFile = false;
let len = input.value.replace(/[ ]/g, "").length;
let v = input.attributes['maxlength'].nodeValue;
let n;
if (v == 0) {
n = 4;
}
if (len < 1 || len > Number(v)) {
n = v;
Toast({
message: (`请输入1-${n}个字符`),
duration: 400
});
this.isEmpty = false;
return false;
}
else {
this.isEmpty = true;
}
} else {
this.isEmpty = true;
}
}
if (this.isEmpty == true) {
let list = [].slice.call(this.requireList), len = list.length, i = 0;
for (i in list) {
let input = list[i];
var iptsName = input.getAttribute('iptkey');

if (input.type == 'file') {
// console.log(this.base64.length);
// console.log(this.getBlob(this.base64).size);
// this.inputs[iptsName] = this.base64;
self.fileKey = iptsName;
} else {
let v = input.value;
let em = v.replace(/[ ]/g, "");
if (/^\d+(\.\d+)?$/.test(em)) {
v = em
}
this.inputs[iptsName] = v;
}
}
// this.data.id = this.id;
// this.data.data = JSON.stringify(this.inputs);

var formData = new FormData();
// let key = document.querySelectorAll('input[type=file]')[0].getAttribute('iptkey') + '';
formData.append(self.fileKey, self.picBlob);
if (!self.isPureFile) {
formData.append('data', JSON.stringify(self.inputs));
}
formData.append('id', self.id);
formData.append('appid', api.appid);
$.ajax({
url: api.baseUrl + '/pic/composite',
type: 'post',
data: formData,
processData: false,
contentType: false,
beforeSend: function () {
Indicator.open({
text: '制作中...',
spinnerType: 'snake'
});
console.log(self.picBlob.size / 1024 / 1024);
},
success: function (data) {
Indicator.close();
self.$router.push({name: 'result', params: {param: JSON.stringify(data)}})
}
})
}
},
getRoundedCanvas (sourceCanvas) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var width = sourceCanvas.width;
var height = sourceCanvas.height;

canvas.width = width;
canvas.height = height;

context.imageSmoothingEnabled = true;
context.drawImage(sourceCanvas, 0, 0, width, height);
context.globalCompositeOperation = 'destination-in';
context.beginPath();
context.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI, true);
context.fill();
return canvas;
},
getBlob(dataURI){
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // mime类型
var byteString = atob(dataURI.split(',')[1]); //base64 解码
var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
var intArray = new Uint8Array(arrayBuffer); //创建视图
for (var i = 0; i < byteString.length; i += 1) {
intArray[i] = byteString.charCodeAt(i);
}
var blob = new Blob([intArray], {type: mimeString}); //转成blob
return blob;
}
},
}