开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 2619|回复: 0
收起左侧

[技术分享] uni-app 拍照图片旋转bug以及解决方法

[复制链接]
发表于 2021-10-29 20:27:41 | 显示全部楼层 |阅读模式   广东省揭阳市

前言:

  • 目前测试图片旋转只会出现在ios H5版本上,咨询过同行和ios原生,图片旋转是会发生在canvas压缩或者裁剪上,原生暂未发现图片旋转。

解决思路:

  • H5版本使用exif-js获取Orientation 获取图片旋转方向,使用canvans进行旋转。

代码

// #ifndef APP-PLUS
import Exif from "exif-js"
// #endif
//H5图片入口
const rotatePic = async function(file,name,success) {
    if(!isPicture(name)) return null;
    let Orientation = 1;  
    await getImageTag(file,(e)=>{
        if(e != undefined) Orientation = e; 
    })

    var img = null;  
    var canvas = null;  
    await comprossImage(file, function(e) {  
        img = e.img;  
        canvas = e.canvas;  
    })  
    let baseStr = '';  

    //如果方向角不为1,都需要进行旋转  
    switch(Orientation){  
        case 6://需要顺时针(向右)90度旋转  
            console.log('(向右)90度旋转');  
            baseStr = rotateImg(img,'right',canvas);  
            break;  
        case 8://需要逆时针(向左)90度旋转  
            console.log('向左)90度旋转');  
            baseStr = rotateImg(img,'left',canvas);  
            break;  

        case 3://需要180度旋转 转两次  
            console.log('需要180度旋转');  
            baseStr = rotateImg(img,'right',canvas, 2);  
            break;  
        default:  
            baseStr = rotateImg(img,'',canvas);  
            break;  
    }  
    return baseStr
}

/**
 * @desc 获取图片信息,使用exif.js库,具体用法请在github中搜索  
 * home.php?mod=space&uid=275307 {Object} file 上传的图片文件   
 * home.php?mod=space&uid=161696 {Promise<Any>} 读取是个异步操作,返回指定的图片信息  
 */  
const getImageTag  = function (file, 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)  
        let _this = this;
        uni.hideLoading()

        uni.getImageInfo({  
            src: file,  
            success(res) {  
                let obj = {
                    src:res.path
                }
                Exif.getData(obj, function () {  

                    let or = Exif.getTag(this,'Orientation');//这个Orientation 就是我们判断需不需要旋转的值了,有1、3、6、8  

                    resolve(suc(or))  
                });  
            }  
        })  
    });  
}

//创建图片
const comprossImage = async (imgSrc, func) => {  
    if(!imgSrc) return 0;  
    return new Promise((resolve, reject) => {  
        uni.getImageInfo({  
            src: imgSrc,  
            success(res) {  
                let img = new Image();  
                img.src = res.path;  

                let canvas = document.createElement('canvas');  

                let obj = new Object();  
                obj.img = img;  
                obj.canvas = canvas;  
                resolve(func(obj));  
            }  
        });  
    })  
}  

//网上提供的旋转function  
const 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, 0, width, height);
        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;  
}

ios 系统版本13.4以上不需要进行图片旋转   ios 13.4以上竖拍 Orientation 依然会得到6 但是图片已经被系统调整到正常使用旋转后会导致图片被旋转2次

//ios 13.4以上不需要进行翻转
const getVersionRotate = ()  => {
    var ua = navigator.userAgent.toLowerCase();
    var ver= ua.match(/cpu iphone os (.*?) like mac os/);
    let b = ver[1].replace(/_/g,".");
    return toNum(b) >= toNum(13.4) ? false : true;
}
//计算版本号大小,转化大小
const toNum = (a)  =>  {
  var a=a.toString();
  var c=a.split('.');
  var num_place=["","0","00","000","0000"],r=num_place.reverse();
  for (var i=0;i<c.length;i++){ 
     var len=c[i].length;       
     c[i]=r[len]+c[i];  
  } 
  var res= c.join(''); 
  return res; 
} 

// #ifndef APP-PLUS

 //处理图片旋转 H5上传入口
 if(getVersionRotate()) {
     _file = await rotatePic (filePath, dir) || filePath;
 }

 // #endif

原生图片旋转解决思路

因为几个测试机未出现图片旋转问题,所以未进行旋转,解决思路为选择图片后 uni.getImageInfo(OBJECT) success中获取orientation 旋转参数,使用plus.zip.compressImage进行原生图片旋转

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表