解决uniapp在h5图片上传后旋转90度问题(editor同样适用)
问题简单描述
以往没有uniapp上传图片的经验,这两天刚接手这个功能,遇到了一系列糟心的事情
1.第一版我使用的插件市场的图片压缩插件,出现的问题:低版本安卓拍照出现闪退白屏等问题
2.第二版我换了个图片压缩插件,出现的问题:
a:上传成功后,提交数据,结果在iOS上不能调用window.webkit关闭当前网页,于是只好ISO做了拦截处理,这不是最严重的,最严重的是
b:图片上传成功后逆时针旋转了90度
解决办法
我也百度参考以往大佬的经验,最后终于完美解决了:
1.导入exif插件
import EXIF from ‘@/utils/exif.js’
2.uni.chooseImage选择上传图片,获取到res后的blod
data() {return {maxSize:10,resImg:''}},
methods: {
insertImage() {uni.chooseImage({count: 1,size:10*1000000,sizeType: ['compressed'],success: (res) => {//这是需求要求的上传限制,可以不要if (parseInt(tempFiles.size) > this.maxSize * 1024 * 1024) {uni.showToast({title: '图片大于'+this.maxSize+'MB!',icon: 'none'})} else {this.resImg = res.tempFilePaths[0]//这就是要的blodthis.detail(this.resImg)} }})},
}
3.调用this.detail方法做图片处理,这里还用到了this.comprossImage图片压缩和this.getImageTag图片方法,以及最后对图片修正处理方法this.rotateImg,直接粘贴就行
//url 就是上面获取到的blodasync detail(url){let maxWidth = 500; let Orientation = 1; //获取图片META信息 await this.getImageTag(url, 'Orientation', function(e) { if(e != undefined) Orientation = e; }) var img = null; var canvas = null; await this.comprossImage(url, maxWidth, function(e) { img = e.img; canvas = e.canvas; }) console.log(Orientation,"Orientation") let baseStr = ''; //如果方向角不为1,都需要进行旋转 switch(Orientation){ case 6://需要顺时针(向右)90度旋转 baseStr = this.rotateImg(img,'right',canvas); break; case 8://需要逆时针(向左)90度旋转 baseStr = this.rotateImg(img,'left',canvas); break; case 3://需要180度旋转 转两次 baseStr = this.rotateImg(img,'right',canvas, 2); break; default: baseStr = this.rotateImg(img,'',canvas); break; } console.log(baseStr,"baseStr")this.uploadImg(baseStr)//图片上传到服务器的方法},//-------------------------------直接粘贴的三个方法async comprossImage(imgSrc, maxWidth, func){ if(!imgSrc) return 0; return new Promise((resolve, reject) => { uni.getImageInfo({ src: imgSrc, success(res) { let img = new Image(); img.src = res.path; console.log(img) let canvas = document.createElement('canvas'); let obj = new Object(); obj.img = img; obj.canvas = canvas; resolve(func(obj)); } }); }) },/** * @desc 获取图片信息,使用exif.js库,具体用法请在github中搜索 * @param {Object} file 上传的图片文件 * @param {String} tag 需要获取的信息 例如:'Orientation'旋转信息 * @return {Promise<Any>} 读取是个异步操作,返回指定的图片信息 */ getImageTag(file, tag, suc){ if (!file) return 0; return new Promise((resolve, reject) => { /* eslint-disable func-names */ // 箭头函数会修改this,所以这里不能用箭头函数 let imgObj = new Image() imgObj.src = file console.log(imgObj) uni.getImageInfo({ src: file, success(res) { EXIF.getData(imgObj, function () { EXIF.getAllTags(this); let or = EXIF.getTag(this,'Orientation');//这个Orientation 就是我们判断需不需要旋转的值了,有1、3、6、8 resolve(suc(or)) }); } }) }); },rotateImg(img, direction, canvas, times = 1){ console.log('开始旋转') //最小与最大旋转方向,图片旋转4次后回到原方向 var min_step = 0; var max_step = 3; if (img == null)return; //img的高度和宽度不能在img元素隐藏后获取,否则会出错 var height = img.height; var width = img.width; let maxWidth = 500; let canvasWidth = width; //图片原始长宽 let canvasHeight = height; let base = canvasWidth/canvasHeight; console.log(maxWidth); if(canvasWidth > maxWidth){ canvasWidth = maxWidth; canvasHeight = Math.floor(canvasWidth/base); } width = canvasWidth; height = canvasHeight; var step = 0; if (step == null) { step = min_step; } if (direction == 'right') { step += times; //旋转到原位置,即超过最大值 step > max_step && (step = min_step); } else if(direction == 'left'){ step -= times; step < min_step && (step = max_step); } else { //不旋转 step = 0; } //旋转角度以弧度值为参数 var degree = step * 90 * Math.PI / 180; var ctx = canvas.getContext('2d'); console.log(degree) console.log(step) switch (step) { case 1: console.log('右旋转 90度') canvas.width = height; canvas.height = width; ctx.rotate(degree); ctx.drawImage(img, 0, -height, width, height); break; case 2: //console.log('旋转 180度') canvas.width = width; canvas.height = height; ctx.rotate(degree); ctx.drawImage(img, -width, -height, width, height); break; case 3: console.log('左旋转 90度') canvas.width = height; canvas.height = width; ctx.rotate(degree); ctx.drawImage(img, -width, 0, width, height); break; default: //不旋转 canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, width, height); break; } let baseStr = canvas.toDataURL("image/jpeg", 1); return baseStr; },//-----------------------------------------------结束uploadImg(tempFilePaths) {console.log(tempFilePaths,"触发上传接口")uni.uploadFile({url: '服务器地址',filePath: tempFilePaths,fileType:"image",header:{"Authorization":'Bearer ' + localStorage.getItem('token')},name: 'file',success: (res) => {uni.hideLoading()let resObj = JSON.parse(res.data)if (resObj.meta.code === 200) {let data = resObj.data.url;console.log(data)} }}
好了,有什么问题欢迎大家一起讨论!最后非常感谢原文(https://ask.dcloud.net.cn/article/36521)提供的经验,谢谢谢谢
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
