vue之vant的h5项目在使用上传图片功能时–ios失败问题
•
移动开发
问题描述:
框架相关描述:
vue之vant的h5项目在使用上传图片功能时–ios失败问题;
问题业务场景描述:
- 在排查问题时,用ios相机拍照的照片(直接调用ios相机拍的照片)进行上传会显示上传失败,而安卓都不会
- 刚开始我以为是图片格式的问题:(看这两种的图片在ios类型是不一样的HEIF和Jpeg,jpeg的格式上传没问题,但是HEIF的上传就会提示上传失败)


解决方案:
- 最终的解决方案是:在afterRead时,将图片进行转流压缩
- 实现代码源码:
hanleImage(file) { let self = this; // 看支持不支持FileReader if (!file || !window.FileReader) return; // 创建一个reader let reader = new FileReader(); // 将图片2将转成 base64 格式 reader.readAsDataURL(file); // 读取成功后的回调 reader.onloadend = function () { let result = this.result; let img = new Image(); img.src = result; console.log('this.result.lengtht:' + this.result.length); //判断图片是否大于512K,是就直接上传,反之压缩图片 512000 if (this.result.length <= 500 * 1024) { console.log('执行此小方案:'); self.headerImage = this.result; //进行转流: let file = self.dataURLtoFile(); console.log("转流之后的值-file:" + file.name); //处理图片方案: let uploadImgUrlData = upLoaderImg(file); uploadImgUrlData .then(result => { self.imageUrlsData.push(result.data); console.log(result.data); file.status = 'success'; file.message = '上传成功'; }) .catch(error => { console.error(error); file.status = 'failed'; file.message = '上传失败'; }); } else { console.log('执行此大方案:'); img.onload = function () { //压缩图片 let data = self.compress(img); self.headerImage = data; //进行转流: let file = self.dataURLtoFile(this.headerImage); //处理图片方案: let uploadImgUrlData = upLoaderImg(file); uploadImgUrlData .then(result => { self.imageUrlsData.push(result.data); console.log(result.data); file.status = 'success'; file.message = '上传成功'; }) .catch(error => { console.error(error); file.status = 'failed'; file.message = '上传失败'; }); }; } }; }, // 压缩图片 compress(img) { let canvas = document.createElement("canvas"); let ctx = canvas.getContext("2d"); //瓦片canvas let tCanvas = document.createElement("canvas"); let tctx = tCanvas.getContext("2d"); // let initSize = img.src.length; let width = img.width; let height = img.height; //如果图片大于四百万像素,计算压缩比并将大小压至400万以下 let ratio; if ((ratio = (width * height) / 4000000) > 1) { // console.log("大于400万像素"); ratio = Math.sqrt(ratio); width /= ratio; height /= ratio; } else { ratio = 1; } canvas.width = width; canvas.height = height; // 铺底色 ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); //如果图片像素大于100万则使用瓦片绘制 let count; if ((count = (width * height) / 1000000) > 1) { // console.log("超过100W像素"); count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片 // 计算每块瓦片的宽和高 let nw = ~~(width / count); let nh = ~~(height / count); tCanvas.width = nw; tCanvas.height = nh; for (let i = 0; i < count; i++) { for (let j = 0; j < count; j++) { tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh); ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh); } } } else { ctx.drawImage(img, 0, 0, width, height); } //进行最小压缩 let ndata = canvas.toDataURL("image/jpeg", 0.1); tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0; return ndata; }, //将base64转换为文件 dataURLtoFile() { console.log('执行转流方法'); // console.log('执行转流方法' + this.headerImage); var arr = this.headerImage.split(","), bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], this.files.name, { type: this.files.type }); },//上传图片的动作方法我是封装在utils里的//upLoaderImg.jsimport axios from 'axios' //引入axiosimport {Toast} from 'vant' //引入Toastasync function upLoaderImg(file) { try { // console.log("上传之前参数:"+file.name) let params = new FormData(); params.append('file', file); let config = { headers: { 'Content-Type': 'multipart/form-data' } }; const res = await axios.post(process.env.VUE_APP_BASE_URL + '/tool/minioUpload', params, config); // console.log("上传之后的结果集:"+res.data.data) if (res.data.flag) { return res.data; } else { Toast.fail(res.data && res.data.msg); throw new Error(res.data); } } catch (error) { Toast.fail('上传失败'); throw error; }}export default upLoaderImg如有问题欢迎批评改正。
本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://www.net2asp.com/e7e1207112.html
