场景:
上传的时候要求图片的大小在2MB一下,所以要压缩图片,App端当时使用的是uni.compressImage(OBJECT)压缩的,H5端需要手写
方法一:
1 <template> 2 <view class="content"> 3 <view @tap="ChooseImage()">点击上传图片</view> 4 </view> 5 </template> 6 7 <script> 8 export default { 9 data() { 10 return { 11 title: 'Hello' 12 } 13 }, 14 onLoad() { 15 16 }, 17 methods: { 18 ChooseImage() { 19 uni.chooseImage({ 20 count: 1, 21 sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 22 sourceType: ['album'], //从相册选择 23 success: res => { 24 const imgSize = res.tempFiles[0] && res.tempFiles[0].size ? res.tempFiles[0].size : 0; 25 const imgName = res.tempFiles[0]&&res.tempFiles[0].name?res.tempFiles[0].name:''; 26 console.log(imgSize) 27 this.photoCompress(res.tempFiles[0], (base64Codes) => { 28 var fl = this.dataURLtoFile(base64Codes,imgName) 29 console.log(fl, "压缩后的文件") 30 }) 31 } 32 }) 33 }, 34 photoCompress(file, objDiv) { 35 var ready = new FileReader(); 36 ready.readAsDataURL(file); 37 const _this = this; 38 ready.onload = function() { 39 var fileResult = this.result; 40 _this.canvasDataURL(fileResult, objDiv) 41 } 42 }, 43 canvasDataURL(path, callback) { 44 var img = new Image(); 45 img.src = path; 46 var objCompressed = {} 47 img.onload = function() { 48 var that = this; 49 //默认压缩后图片规格 50 var quality = 0.7; 51 var w = that.width; 52 var h = that.height; 53 var scale = w / h; 54 //实际要求 55 w = objCompressed.width || w; 56 h = objCompressed.height || (w / scale); 57 //生成canvas 58 var canvas = document.createElement('canvas'); 59 var ctx = canvas.getContext('2d'); 60 // 创建属性节点 61 var anw = document.createAttribute("width"); 62 anw.nodeValue = w; 63 var anh = document.createAttribute("height"); 64 anh.nodeValue = h; 65 canvas.setAttributeNode(anw); 66 canvas.setAttributeNode(anh); 67 ctx.drawImage(that, 0, 0, w, h); 68 69 var base64 = canvas.toDataURL('image/jpeg', quality); 70 // 回调函数返回base64的值 71 callback(base64); 72 } 73 }, 74 dataURLtoFile(dataurl,filename) { 75 var arr = dataurl.split(","), 76 mime = arr[0].match(/:(.*?);/)[1], 77 bstr = atob(arr[1]), 78 n = bstr.length, 79 u8arr = new Uint8Array(n); 80 while (n--) { 81 u8arr[n] = bstr.charCodeAt(n); 82 } 83 return new File([u8arr],filename, { type: mime }); 84 } 85 } 86 } 87 </script> 88 89 <style> 90 91 </style>
通过压缩获取到File的对象,如果直接使用之前上传图片的uni.uploadFile(OBJECT)(详情见:
uni.uploadFile(OBJECT) | uni-app官网 (dcloud.io) 会上传不成功,具体的问题不太清楚好像是file的path的问题,后端的同事不想动他的代码,只能自己动手了,直接写原生的ajax上传
function fileUpload(i) { console.log('fileUpload ---->', requestInfo) let item = requestInfo.files[i]; let fileData = { fileIndex: i, files: requestInfo.files, ...item }; var formdata = new FormData(); formdata.append("file", item); var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", function(e) { var percentComplete = Math.round(e.loaded * 100 / e.total); requestInfo.onProgressUpdate && requestInfo.onProgressUpdate(Object.assign({}, fileData, percentComplete.toString() + '%')); }); xhr.addEventListener("load", function(e) { requestInfo.uploadComplete && requestInfo.uploadComplete(Object.assign({}, fileData, xhr.responseText)); }); xhr.addEventListener("error", function(e) { requestInfo.uploadError && requestInfo.uploadError(Object.assign({}, fileData, e)); }); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { requestInfo.onEachUpdate && requestInfo.onEachUpdate({ data: xhr.responseText, ...fileData }); fileList.push(xhr.responseText); if (len <= i) { resolve(fileList); } else { fileUpload(i + 1); } } else if (xhr.readyState === 4) { reject('err'); } } xhr.open("post", requestInfo.url, true); xhr.setRequestHeader('platform', requestInfo.header.platform); xhr.setRequestHeader('Access-Token', requestInfo.header['Access-Token']); xhr.send(formdata); }
问题解决
使用axios上传也可以
方法二:
1.选择图片
uni.chooseImage({ count: 6, //默认9 // sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有 sourceType: ['album'], //从相册选择 success: function (res) { let tempPaths = res.tempFilePaths if(tempPaths.length + _this.imgList.length > 6) { uni.showToast({ title: '上传图片最多可选6张', icon: 'none' }) } else { _this.imgList = _this.imgList.concat(tempPaths) _this.compressImage() } } })
2.
compressImage(){ for(let i in this.imgList){ let imgFile = this.imgList[i] this.getImageInfo(imgFile) } },
3.获取图片信息并压缩
// 获取图片信息 getImageInfo(src) { let _this = this uni.getImageInfo({ src, success(res) { console.log('压缩前', res) let canvasWidth = res.width //图片原始长宽 let canvasHeight = res.height let img = new Image() img.src = res.path let canvas = document.createElement('canvas'); let ctx = canvas.getContext('2d') canvas.width = canvasWidth / 2 canvas.height = canvasHeight / 2 ctx.drawImage(img, 0, 0, canvasWidth / 2, canvasHeight / 2) canvas.toBlob(function(fileSrc) { let imgSrc = window.URL.createObjectURL(fileSrc) console.log('压缩后', imgSrc) _this.uploadFile(imgSrc) }) } }) },
4.上传
// 上传图片 uploadFile(filePath) { let _this = this uni.uploadFile({ url: '/api/api/Profile/UploadImg', name: 'file', filePath, formData: {}, success: (res) => { let { data } = JSON.parse(res.data) _this.imgResults.push(data) }, fail: (err) => { uni.showToast({ title: err.errMsg, icon: 'none' }) } }); },
来源:https://juejin.cn/post/7044719449252823077