Vue项目解决苹果手机拍照上传图片翻转问题

input type=“file”方式上传

在项目中,这里用到了input type="file"方式上传图片

<input @change="upImg(6)" ref="foreheadCir" type="file" accept="image/*" mutiple="mutiple">

在项目测试中发现,使用苹果手机点击input标签直接调用相机功能上传照片(从相册选择图片上传则正常),却发现后台接收到的图片被翻转了90度,而在安卓机测试却不会,最终解决的方法是:使用npm库的exif-js插件。

解决步骤如下:

step1安装插件:

cnpm install exif-js --save

step2在当前组件引用插件:

import Vue from "vue";
import EXIF from "exif-js";
Vue.use(EXIF);    //全局申明

step3 获取change事件传递过来的图片(例如:this.$refs.foreheadCir.files[0])

     var Orientation = null;
        if (file) {
          if (navigator.userAgent.match(/Android/i)) {
            console.log("正在上传,请稍后...");
            var rFilter = /^(image\/jpeg|image\/png)$/i; // 检查图片格式
            if (!rFilter.test(file.type)) {
              //showMyTips("请选择jpeg、png格式的图片", false);
              return;
            }
            console.log("2222"+Orientation);
            if (/^image/.test(file.type)) {
              // 创建一个reader
              var reader = new FileReader();
              // 将图片将转成 base64 格式
              reader.readAsDataURL(file);
              // 读取成功后的回调
              reader.onloadend = function (e) {
                /*var obj={};
                obj["src"]=this.result;
                self.upPhoto(index,obj["src"],areaId);//传给后台*/
                var base64S = null;
                var img = new Image,
                  width = 2048, //image resize
                  quality = 0.8, //image quality
                  canvas = document.createElement("canvas"),
                  drawer = canvas.getContext("2d");
                  img.src = this.result;
                  img.onload = function() {
                    canvas.width = width;
                    canvas.height = width * (img.height / img.width);
                    drawer.drawImage(img, 0, 0, canvas.width, canvas.height);
                    base64S = canvas.toDataURL("image/jpeg", quality);
                    console.log(img.src);
                    self.upPhoto(index,base64S,areaId);
                  }

              }
            }
          }else{
            console.log("正在上传,请稍后...");
            var rFilter = /^(image\/jpeg|image\/png)$/i; // 检查图片格式
            if (!rFilter.test(file.type)) {
              //showMyTips("请选择jpeg、png格式的图片", false);
              return;
            }
            // var URL = URL || webkitURL;
            //获取照片方向角属性,用户旋转控制
            EXIF.getData(file, function() {
              // alert(EXIF.pretty(this));
              EXIF.getAllTags(this);
              //alert(EXIF.getTag(this, 'Orientation'));
              Orientation = EXIF.getTag(this, 'Orientation');
              //return;
            });

            var oReader = new FileReader();
            oReader.onload = function(e) {
              //var blob = URL.createObjectURL(file);
              //_compress(blob, file, basePath);
              var image = new Image();
              image.src = e.target.result;
              image.onload = function() {
                var expectWidth = this.naturalWidth;
                var expectHeight = this.naturalHeight;

                /*            if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
                 expectWidth = 800;
                 expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
                 } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
                 expectHeight = 1200;
                 expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
                 }*/
                var canvas = document.createElement("canvas");
                var ctx = canvas.getContext("2d");
                canvas.width = expectWidth;
                canvas.height = expectHeight;
                ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
                var base64 = null;
                //修复ios
                if (navigator.userAgent.match(/iphone/i)) {
                  console.log('iphone');
//                  alert("苹果");
                  //alert(expectWidth + ',' + expectHeight);
                  //如果方向角不为1,都需要进行旋转 added by lzk
                  if(Orientation != "" && Orientation != 1){
//                    alert('旋转处理');
                    switch(Orientation){
                      case 6://需要顺时针(向左)90度旋转
//                      alert('需要顺时针(向左)90度旋转');
                        self.rotateImg(this,'left',canvas);
                        break;
                      case 8://需要逆时针(向右)90度旋转
//                      alert('需要顺时针(向右)90度旋转');
                        self.rotateImg(this,'right',canvas);
                        break;
                      case 3://需要180度旋转
//                      alert('需要180度旋转');
                        /*self.rotateImg(this,'right',canvas);//转两次
                        self.rotateImg(this,'right',canvas);*/
                        self.rotateImg(this,'turntwo',canvas);
                        break;
                    }
                  }

                  /*var mpImg = new MegaPixImage(image);
                   mpImg.render(canvas, {
                   maxWidth: 800,
                   maxHeight: 1200,
                   quality: 0.8,
                   orientation: 8
                   });*/
                  base64 = canvas.toDataURL("image/jpeg", 0.8);
                }/*else if (navigator.userAgent.match(/Android/i)) {// 修复android
                 //                var encoder = new JPEGEncoder();
                 //                base64 = encoder.encode(ctx.getImageData(0, 0, expectWidth, expectHeight), 80);
                 alert("安卓");
                 base64 = ctx.getImageData(0, 0, expectWidth, expectHeight);
                 }*/else{
                  //alert(Orientation);
//                  alert("其它");
                  if(Orientation != "" && Orientation != 1){
                    //alert('旋转处理');
                    switch(Orientation){
                      case 6://需要顺时针(向左)90度旋转
//                      alert('需要顺时针(向左)90度旋转');
                        self.rotateImg(this,'left',canvas);
                        break;
                      case 8://需要逆时针(向右)90度旋转
//                      alert('需要顺时针(向右)90度旋转');
                        self.rotateImg(this,'right',canvas);
                        break;
                      case 3://需要180度旋转
//                      alert('需要180度旋转');
                        /*self.rotateImg(this,'right',canvas);//转两次
                        self.rotateImg(this,'right',canvas);*/
                        self.rotateImg(this,'turntwo',canvas);
                        break;
                    }
                  }

                  base64 = canvas.toDataURL("image/jpeg", 0.8);
                }
                self.upPhoto(index,base64,areaId);//传给后台
//              $("#myImage").attr("src", base64);
              };
            };
            oReader.readAsDataURL(file);
          }
        }

step4通过画布,对图片进行旋转处理:

      rotateImg:function(img, direction,canvas) {
        console.log("拉拉");
        //alert(img);
        //最小与最大旋转方向,图片旋转4次后回到原方向
        var min_step = 0;
        var max_step = 3;
        //var img = document.getElementById(pid);
        if (img == null)return;
        //img的高度和宽度不能在img元素隐藏后获取,否则会出错
        var height = img.height;
        var width = img.width;
        //var step = img.getAttribute('step');
        var step = 2;
        if (step == null) {
          step = min_step;
        }
        if (direction == 'right') {
          step++;
          //旋转到原位置,即超过最大值
          step > max_step && (step = min_step);
        } else {
          step--;
          step < min_step && (step = max_step);
        }
        //img.setAttribute('step', step);
        /*var canvas = document.getElementById('pic_' + pid);
         if (canvas == null) {
         img.style.display = 'none';
         canvas = document.createElement('canvas');
         canvas.setAttribute('id', 'pic_' + pid);
         img.parentNode.appendChild(canvas);
         }  */
        //旋转角度以弧度值为参数
        var degree = step * 90 * Math.PI / 180;
        var ctx = canvas.getContext('2d');
        switch (step) {
          case 0:
            canvas.width = width;
            canvas.height = height;
            ctx.drawImage(img, 0, 0);
            break;
          case 1:
            canvas.width = height;
            canvas.height = width;
            ctx.rotate(degree);
            ctx.drawImage(img, 0, -height);
            break;
          case 2:
            canvas.width = width;
            canvas.height = height;
            ctx.rotate(degree);
            ctx.drawImage(img, -width, -height);
            break;
          case 3:
            canvas.width = height;
            canvas.height = width;
            ctx.rotate(degree);
            ctx.drawImage(img, -width, 0);
            break;
        }
      },

stpe5最后将生成的图片转换为base64格式,通过ajax请求发送給后端。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容