原生input拍照以及上传图片压缩旋转

637 阅读2分钟

添加input

<input class="camera-input" accept="image/*" type="file" @change="fileChange($event)" id="input" />

orientation判断图片是拍照(横屏还是竖屏,什么机型需要旋转)还是本地图片,1显示正常,竖拍的参数为 6顺时针90°,8逆时针90°,3顺时针180°

  getOrientation(file, callback) {  
  var reader = new FileReader();  
  reader.onload = function(e) {  
    var view = new DataView(e.target.result);  
    if (view.getUint16(0, false) != 0xffd8) return callback(-2);  
    var length = view.byteLength,  
      offset = 2;  
    while (offset < length) {  
      var marker = view.getUint16(offset, false);  
      offset += 2;  
      if (marker == 0xffe1) {  
        if (view.getUint32((offset += 2), false) != 0x45786966)  
          return callback(-1);  
        var little = view.getUint16((offset += 6), false) == 0x4949;  
        offset += view.getUint32(offset + 4, little);  
        var tags = view.getUint16(offset, little);  
        offset += 2;  
        for (var i = 0; i < tags; i++)  
          if (view.getUint16(offset + i * 12, little) == 0x0112)  
            return callback(view.getUint16(offset + i * 12 + 8, little));  
      } else if ((marker & 0xff00) != 0xff00) break;  
      else offset += view.getUint16(offset, false);  
    }  
    return callback(-1);  
  };  
  reader.readAsArrayBuffer(file.slice(0, 64 * 1024));  
},  

canvas实现图片压缩,ndata的第二个参数是压缩比例

compress(event) {
  var that = this;
  var file = event.target.files;
  var reader = new FileReader(),
    imgFile = file[0];
  if (imgFile.type.indexOf("image") == 0) {
    reader.readAsDataURL(imgFile);
  } else {
    this.$Message.infor("文件类型仅为图片");
  }
  let img = new Image();
  reader.onload = function(e) {
    img.src = e.target.result;
  };
  var imgP = new Promise((resolve, reject) => {
    img.onload = () => {
      var canvas = document.createElement("canvas");
      var ctx = canvas.getContext("2d");
      //    瓦片canvas
      var tCanvas = document.createElement("canvas");
      var tctx = tCanvas.getContext("2d");
      var initSize = img.src.length;
      var width = img.width;
      var height = img.height;
      //图片像素大于400万像素,计算压缩到400万以下
      var ratio;
      if ((ratio = (width * height) / 4000000) > 1) {
        ratio = Math.sqrt(ratio);
        width /= ratio;
        height /= ratio;
      } else {
        ratio = 1;
      }
      canvas.width = width;
      canvas.height = height;
      ctx.fillStyle = "#fff";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      //如果图片太大则使用瓦片绘制
      var count;
      if ((count = (width * height) / 1000000 > 1)) {
        count = ~~(Math.sqrt(count) + 1); //计算分成的瓦片数
        var nw = ~~(width / count);
        var nh = ~~(height / count);
        tCanvas.width = nw;
        tCanvas.height = nh;
        for (var i = 0; i < count; i++) {
          for (var j = 0; j < count; j++) {
            tctx.drawImage(
              img,
              i * nw * ratio,
              j * nh * ratio,
              nw * ratio,
              nh * ratio,
              0,
              0,
              nw,
              nh
            );
            ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
          }
        }
      } else {
        ctx.drawImage(img, 0, 0, width, height);
      }
      //进行最小压缩
      var ndata = canvas.toDataURL("image/jpeg", 0.3);
      tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
      resolve(ndata);
    };
  });
  return Promise.all([imgP]);
},

图片旋转

rotate(imgData, number) {  
  var that = this;  
  var img = new Image();  
  img.src = imgData;
  var imgR = new Promise((resolve, reject) => {
    img.onload = () => {
      let degree = 0,
        drawHeight,
        drawWidth;
      drawHeight = img.naturalHeight;
      drawWidth = img.naturalWidth;
      let maxSide = Math.max(drawWidth, drawHeight);
      // if (maxSide === drawWidth) {
      //   //判断需要旋转的角度
      //   degree = 90;
      // } else {
      //   degree = 0;
      // }
      // if (drawWidth > drawHeight) {
      //   that.resultImgShow = true;
      // } else {
      //   that.resultImgShow = false;
      // }
      // console.log( drawWidth,drawHeight,'drawWidth')
      //判断手机图片是哪里来的,1显示正常,竖拍的参数为 6顺时针90°,8逆时针90°,3顺时针180°
      if (number == 1) {
        degree = 360;
      } else if (number == 6) {
        degree = 90;
      } else if (number == 8) {
        degree = 270;
      } else if (number == 3) {
        degree = 180;
      } else {
        degree = 0;
      }
      var canvas = document.createElement("canvas");
      canvas.width = drawWidth;
      canvas.height = drawHeight;
      var context = canvas.getContext("2d");
      context.translate(drawWidth / 2, drawHeight / 2); //这一行和下下一行的作用是修改选择中心
      context.rotate((degree * Math.PI) / 180); //旋转图片
      context.translate(-drawWidth / 2, -drawHeight / 2); //这一行和上上一行的作用是修改选择中心
      context.drawImage(img, 0, 0, drawWidth, drawHeight);
      var ndata = canvas.toDataURL("image/jpeg", 1);
      context.width = context.height = 0;
      resolve(ndata);
    };
  });
  return Promise.all([imgR]);
},

调用上面函数

fileChange(el) {
  var that = this;
  var compressImg = this.compress(el);
  var input = document.getElementById("input");
  // 调用压缩图片
  compressImg.then(data => {
    //orientation判断手机图片是哪里来的,1显示正常,竖拍的参数为 6顺时针90°,8逆时针90°,3顺时针180°
    this.getOrientation(input.files[0], function(orientation) {
      var rotateImg = that.rotate(data[0], orientation);
      rotateImg.then(data => {
        that.gomyDetailsIf = false;
        that.resultImg = data[0];
      });
    });
  });
},