关于vue中图片压缩上传以及旋转图片

大体的思路是

利用FileReader,读取blob对象,或者是file对象,将图片转化为data uri的形式。

使用canvas,在页面上新建一个画布,利用canvas提供的API,将图片画入这个画布当中。

利用canvas.toDataURL(),进行图片的压缩,得到图片的data uri的值

上传文件。

我将以上步骤封装成一个方法:

compress(file, quality, callback) {

          if (!window.FileReader || !window.Blob) {

              return errorHandler('您的浏览器不支持图片压缩')();

          }

          var reader = new FileReader();

          var mimeType = file.type || 'image/jpeg';

          reader.onload = createImage;

          reader.onerror = errorHandler('图片读取失败!');

          reader.readAsDataURL(file);

          function createImage() {

              var dataURL = this.result;

              var image = new Image();

              image.onload = compressImage;

              image.onerror = errorHandler('图片加载失败');

              image.src = dataURL;

          }

          function compressImage() {

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

              var ctx;

              var dataURI;

              var result;

              canvas.width = this.naturalWidth;

              canvas.height = this.naturalHeight;

              ctx = canvas.getContext('2d');

              ctx.drawImage(this, 0, 0);

              dataURI = canvas.toDataURL(mimeType, quality);

              result = dataURIToBlob(dataURI);

              callback(null, result);

          }

          function dataURIToBlob(dataURI) {

              var type = dataURI.match(/data:([^;]+)/)[1];

              var base64 = dataURI.replace(/^[^,]+,/, '');

              var byteString = atob(base64);

              var ia = new Uint8Array(byteString.length);

              for (var i = 0; i < byteString.length; i++) {

                  ia[i] = byteString.charCodeAt(i);

              }

              // var blob = getBlob([ia]);

              return new Blob([ia], {type: type});

          }

          function errorHandler(message) {

              return function () {

                  var error = new Error('Compression Error:', message);

                  callback(error, null);

              };

          }

      },

然后在在onchange事件中调用上面方法:

onUploadIdcard(e) {

          var _this = this

          let file = e.target.files[0];

          var formData = new FormData();

          _this.compress(file, 0.5, function (err, data) {

              if (err) {

                  console.log(err);

                  return;

              }

              formData.append('file', data,'image.png');

              $.ajax({

                url: '你的接口',//这里是后台接口需要换掉

                type: 'POST',

                dataType: 'json',

                cache: false,

                data: formData,

                processData: false,

                contentType: false,

                success: (res) => {

                  if (res.code === 200) {

                  }else if(res.code==40107){

                  }

                },error: function(err) {

                }

              });

          });

      },

搞定

我这里设置的用 canvas重绘时 图像宽高不变,只改变质量,想改变宽高的可以修改canvas.width和canvas.height,改变质量就修改compress方法中的第二个参数0.5。

另外注意部分安卓机型不支持blob类型,会导致选择图片后无法上传,自动跳页;这里不能直接用new Blob();这时在dataURIToBlob方法中要改成兼容性写法:

function dataURIToBlob(dataURI) {

              var type = dataURI.match(/data:([^;]+)/)[1];

              var base64 = dataURI.replace(/^[^,]+,/, '');

              var byteString = atob(base64);

              var ia = new Uint8Array(byteString.length);

              for (var i = 0; i < byteString.length; i++) {

                  ia[i] = byteString.charCodeAt(i);

              }

              var blob;

              try {

                blob = new Blob([ia], {type: 'image/jpg'});

              } catch (e) {

                window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;

                if(e.name === 'TypeError' && window.BlobBuilder){

                  var blobBuilder = new BlobBuilder();

                  blobBuilder.append(ia);

                  blob = blobBuilder.getBlob('image/jpg');

                }

              }

              return blob

          }

OK

还有就是iOS和部分Android机型拍照后图片自动旋转,原因在另一篇文章中说明了,这里要用到exif.js,

npm install exif-js --save

然后在当前页面

import Exif from 'exif-js'

在封装的compress方法开头用exif获取方向

let Orientation;

//去获取拍照时的信息,解决拍出来的照片旋转问题 

Exif.getData(file, function(){ 

     Orientation = Exif.getTag(this, 'Orientation'); 

});

修改compressImage() 方法,

function compressImage() {

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

              var ctx;

              var dataURI;

              var result;

              var degree = 0,drawWidth,drawHeight,width,height;

              drawWidth = this.naturalWidth;

              drawHeight = this.naturalHeight;

              canvas.width=width=drawWidth;

              canvas.height=height=drawHeight;

              ctx = canvas.getContext('2d');

              //判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式

              if(Orientation != "" && Orientation != 1){

                  switch(Orientation){

                        //iphone横屏拍摄,此时home键在左侧

                      case 3:

                            degree=180;

                            drawWidth=-width;

                            drawHeight=-height;

                              break;

                    //iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)

                        case 6:

                              canvas.width=height;

                              canvas.height=width;

                              degree=90;

                              drawWidth=width;

                              drawHeight=-height;

                              break;

                        //iphone竖屏拍摄,此时home键在上方

                        case 8:

                                canvas.width=height;

                                canvas.height=width;

                                degree=270;

                                drawWidth=-width;

                                drawHeight=height;

                                break;

                    }

              }

              //使用canvas旋转校正

              ctx.rotate(degree*Math.PI/180);

              ctx.drawImage(this, 0, 0, drawWidth, drawHeight);

              dataURI = canvas.toDataURL(mimeType, quality);

              result = dataURIToBlob(dataURI);

              callback(null, result);

          }

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

推荐阅读更多精彩内容

  • 业务有个需求,要做图片预览上传,过去都是客户端上传给后端,后端返回url前端进行预览,现在其实可以不依赖后端做预览...
    诺花生阅读 4,180评论 1 3
  • 一、作者介绍 纳西姆·尼古拉斯·塔勒布( Nassim Nicholas Taleb)畅销书《黑天鹅》、《随机漫步...
    3分钟即兴演讲阅读 596评论 1 0
  • 初到杭州的那些天,一肚子的委屈。这里的天空似乎不太欢迎我这个西北土著,像被长工白吃了饭的财主的脸,阴沉沉的拉着。心...
    爱佛僧阅读 412评论 7 10
  • 每次总是以为感冒很快就要好了,结果情况更糟糕。昨晚上已经没有什么感冒的迹象的,没有想到今早上起床后,严重咳嗽,胸口...
    罗xuexue阅读 285评论 0 0