1.图片上传
使用formdata进行上传处理
//上传事件
uplodaData(){
var that = this
//上一次提交未结束前,禁止第二次提交,避免重复上传
//upstate代表上传状态
if(this.upState==false){
return false
}
this.upState=false
//当图片上传时,进入加载状态
uni.showLoading({
title:'上传中...'
})
var form = new FormData();
form.append("后台参数", canshu);
//当上传图片数量大于0时上传
//showpicture存储对象
if(this.img_num>=1&&this.img_modal=='unlimit'){
this.show_picture.forEach((item,index,arr)=>{
if(index>0){form.append("file",arr[index].file)}
//判断循环结束进行上传
if(index==this.show_picture.length-1){
ajaxSubmit()
}
})
}
else{
this.upState = true
uni.showToast({
title:'请上传照片!',icon:'none'
})
}
function ajaxSubmit(){
$.ajax({
url:baseUrl+'',
type:"POST",
data:form,
processData:false,// 告诉jquery不要处理发送的数据
contentType:false,// 告诉jquery不要设置content-Type请求头
xhr: function() {
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.onprogress = function(progress) {
if (progress.lengthComputable) {
var loaded = progress.loaded;//已经上传大小情况
var tot = progress.total;//附件总大小
var per = Math.floor(100*loaded/tot); //已经上传的百分比
console.log('百分比 = '+progress.loaded / progress.total * 100);
}
};
xhr.upload.onloadstart = function() {
console.log('started...');
};
}
return xhr;
},
success:function(res){
that.upState = true
uni.hideLoading()
uni.showToast({
title:'提交成功!',icon:'none'
})
},
error(err){
console.log(err);
}
});
}
}
2.图片压缩
/*
三个参数
file:一个是文件(类型是图片格式),
w:一个是文件压缩的后宽度,宽度越小,字节越小
objDiv:一个是容器或者回调函数
*/
photoCompress(file,w,objDiv){
var that = this
var ready=new FileReader();
/*开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.*/
ready.readAsDataURL(file);
var filename = file.name
ready.onload=function(){
var re=this.result;
that.canvasDataURL(filename,re,w,objDiv)
}
},
canvasDataURL(filename,path, obj, callback){
var img = new Image();
img.src = path;
img.onload = function(){
var that = this;
// 默认按比例压缩
var w = that.width,
h = that.height,
scale = w / h;
w = obj.width || w;
h = obj.height || (w / scale);
var quality = 0.2; // 默认图片质量为0.2
//生成canvas
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// 创建属性节点
var anw = document.createAttribute("width");
anw.nodeValue = w;
var anh = document.createAttribute("height");
anh.nodeValue = h;
canvas.setAttributeNode(anw);
canvas.setAttributeNode(anh);
ctx.drawImage(that, 0, 0, w, h);
// 图像质量
if(obj.quality && obj.quality <= 1 && obj.quality > 0){
quality = obj.quality;
}
// quality值越小,所绘制出的图像越模糊
var base64 = canvas.toDataURL('image/jpeg', quality);
function dataURLtoFile(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 });
}
const file = dataURLtoFile(base64,filename);
// 回调函数返回base64的值
callback(file);
}
},
这样调用使用压缩
that.photoCompress(fileObj, {
quality: 0.2//压缩比率
}, function(base64Codes){
//base64Codes为压缩后的file文件
});
3.图片旋转 (要提前引入EXIF文件) 注意:转化结束后的图片是blob文件,如果通用是file上传的话,这里就会报错。需要进行blob转化file处理。 再提一个踩过的坑,由于我在转fiel的时候将lastModified获取了当前时间,然后图片变大了近乎2倍,不知道为什么这样...还是乖乖取消掉了。
//这样使用以及处理bolb转file
that.fixImageOrientation(files).then(file_blob=>{
//blog 转file文件
let fileRea = new window.File([file_blob], 'initpicture.png', {type: 'image/jpeg'})
//进行下一步处理
**
})
/**
* 修正图片旋转角度问题
* @param {file} 原图片
* @return {Promise} resolved promise 返回纠正后的新图片
*/
fixImageOrientation (file) {
var that = this
return new Promise((resolve, reject) => {
// 获取图片
const img = new Image();
img.crossOrigin = "anonymous";
img.src = window.URL.createObjectURL(file);
img.onerror = () =>{
resolve(file)
};
img.onload = () => {
// 获取图片元数据(EXIF 变量是引入的 exif-js 库暴露的全局变量)
EXIF.getData(img, function() {
// 获取图片旋转标志位
var orientation = EXIF.getTag(this, "Orientation");
// 根据旋转角度,在画布上对图片进行旋转
if (orientation === 3 || orientation === 6 || orientation === 8) {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
switch (orientation) {
case 3: // 旋转180°
canvas.width = img.width;
canvas.height = img.height;
ctx.rotate((180 * Math.PI) / 180);
ctx.drawImage(img, -img.width, -img.height, img.width, img.height);
break;
case 6: // 旋转90°
canvas.width = img.height;
canvas.height = img.width;
ctx.rotate((90 * Math.PI) / 180);
ctx.drawImage(img, 0, -img.height, img.width, img.height);
break;
case 8: // 旋转-90°
canvas.width = img.height;
canvas.height = img.width;
ctx.rotate((-90 * Math.PI) / 180);
ctx.drawImage(img, -img.width, 0, img.width, img.height);
break;
}
// 返回新图片
canvas.toBlob(file => resolve(file), 'image/jpeg', 0.95)
} else {
return resolve(file);
}
});
};
});
},
4.图片回调再次上传
当图片上传给后台,调用的时候后台会返回给你一个url地址,这个时候你就需要将这个url转化为file进行下次上传(备注:觉得后台处理这有点问题,转来转去的确实麻烦)后台会判断这个file的name,如果这个name是后台给的name而不是新的,就会跳过上传。
//url转file文件
changeFile(url){
//将url转化为base64
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
var ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
var dataURL = canvas.toDataURL("image/"+ext);
return dataURL;
}
//将base64转换为文件
function dataURLtoFile(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 });
}
//循环处理 file为空的数据
this.show_picture.forEach((item,index,arr)=>{
let that = this
//当file为空时将url转化为file
if(arr[index].file==''){
let image = new Image();
image.crossOrigin = 'anonymous'//避免跨域
image.src = arr[index].src
image.onload = function(){
let base64 = getBase64Image(image);
var file = dataURLtoFile(base64,arr[index].annex_name);
arr[index].file = file
}
}
})
},
上述步骤基本实现了图片的上传问题。后期继续优化,注:图片懒加载的没有放到这里哦!!