关于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);

          }

你可能感兴趣的:(关于vue中图片压缩上传以及旋转图片)