91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue實現壓縮圖片預覽并上傳功能(promise封裝)

發布時間:2020-09-04 21:50:40 來源:腳本之家 閱讀:803 作者:zhaohanqq 欄目:web開發

本文實例為大家分享了vue實現壓縮圖片預覽并上傳的具體代碼,供大家參考,具體內容如下

主要用到filereader、canvas 以及 formdata 這三個h6的api

過程大致分為三步:

用戶使用input file上傳圖片的時候,用filereader讀取用戶上傳的圖片數據(base64格式)
把圖片數據傳入img對象,然后將img繪制到canvas上,再調用canvas.toDataURL對圖片進行壓縮
獲取到壓縮后的base64格式圖片數據,轉成二進制塞入formdata,再通過XmlHttpRequest提交formdata。

模板:

<template>
 <div class="image-box">
 <input type="file" accept="image/*" @change="imageHandle">
 <img ref="upImg"/>
 </div>
</template>

獲取圖片數據

methods: {
  //監聽input file的change事件
 imageHandle(e) {
  //**這個是必不可少的,在下面的reader.onload中this就不再指vm了**
  let that = this;
  let maxSize = 100 * 1024;
  let files = e.srcElement.files;
  if (!files.length) return; //文件長度大于0
  if (!/^image\//.test(files[0].type)) return; //必須是圖片才處理
  if (!window.FileReader) return; //支持FileReader
  //創建filereader對象
  let reader = new FileReader();
  reader.readAsDataURL(files[0]); //將圖片轉成base64格式
  reader.onload = function() {
  let result = this.result;
  let img = new Image();
  img.src = result;
  let formdata = new FormData();
  if (this.result.length <= maxSize) {
   that.$refs.upImg.src = result; //預覽圖片
   img = null;
   //上傳圖片
   formdata.append("image", that._upload(result, files[0].name, files[0].type));
   that.$store.dispatch("uploadImage", formdata)
    .then(data => {
     if (data === 1) {
     that.$toast("上傳成功", "success");
     } else if (data === -1) {
     that.$toast("圖片為空", "error");
     } else {
     that.$toast("上傳失敗", "error");
     }
    })
    .catch(error => that.$toast("上傳失敗", "error"));
  } else {
   img.onload = function() {
   //壓縮圖片
   let data = that._compress(img);
   //圖片預覽
   that.$refs.upImg.src = data;
   //上傳圖片
   formdata.append("image", that._upload(data, files[0].name, files[0].type));
   that.$store.dispatch("uploadImage", formdata)
     .then(data => {
      if (data === 1) {
      that.$toast("上傳成功", "success");
      } else if (data === -1) {
      that.$toast("圖片為空", "error");
      } else {
      that.$toast("上傳失敗", "error");
      }
     })
     .catch(error => that.$toast("上傳失敗", "error"));
   };
  }
  };
 },

壓縮圖片

在IOS中,canvas繪制圖片是有兩個限制的:

首先是圖片的大小,如果圖片的大小超過兩百萬像素,圖片也是無法繪制到canvas上的,調用drawImage的時候不會報錯,但是你用toDataURL獲取圖片數據的時候獲取到的是空的圖片數據。

再者就是canvas的大小有限制,如果canvas的大小大于大概五百萬像素(即寬高乘積)的時候,不僅圖片畫不出來,其他什么東西也都是畫不出來的。

應對第一種限制,處理辦法就是瓦片繪制了。瓦片繪制,也就是將圖片分割成多塊繪制到canvas上,我代碼里的做法是把圖片分割成100萬像素一塊的大小,再繪制到canvas上。

而應對第二種限制,我的處理辦法是對圖片的寬高進行適當壓縮,我代碼里為了保險起見,設的上限是四百萬像素,如果圖片大于四百萬像素就壓縮到小于四百萬像素。四百萬像素的圖片應該夠了,算起來寬高都有2000X2000了。

如此一來就解決了IOS上的兩種限制了。

除了上面所述的限制,還有兩個坑,一個就是canvas的toDataURL是只能壓縮jpg的,當用戶上傳的圖片是png的話,就需要轉成jpg,也就是統一用canvas.toDataURL(‘image/jpeg', 0.1) , 類型統一設成jpeg,而壓縮比就自己控制了。

另一個就是如果是png轉jpg,繪制到canvas上的時候,canvas存在透明區域的話,當轉成jpg的時候透明區域會變成黑色,因為canvas的透明像素默認為rgba(0,0,0,0),所以轉成jpg就變成rgba(0,0,0,1)了,也就是透明背景會變成了黑色。解決辦法就是繪制之前在canvas上鋪一層白色的底色。

_compress(img) {
  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext("2d");
  //瓦片
  let tCanvas = document.createElement("canvas");
  let tctx = tCanvas.getContext("2d");
  let initSize = img.src.length;
  let width = img.width;
  let height = img.height;
  //如果圖片大于四百萬像素,計算壓縮比并將大小壓至400萬以下
  let ratio;
  if ((ratio = (width * height) / 4000000) > 1) {
  ratio = Math.sqrt(ratio);
  widht /= ratio;
  height /= ratio;
  } else {
  ratio = 1;
  }
  canvas.width = width;
  canvas.height = height;
  //鋪底色
  ctx.fillStyle = "#fff";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  //如果圖片像素大于100萬則使用瓦片繪制
  let count;
  if ((count = (width * height) / 1000000) > 1) {
  count = ~~(Math.sqrt(count) + 1); //計算要分成多少瓦片,~~在這里表示取整
  //計算每塊瓦片的寬高
  let nw = ~~(width / count);
  let nh = ~~(height / count);
  tCanvas.width = nw;
  tCanvas.height = nh;
  for (let i = 0; i < count; i++) {
   for (let 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, canvas.width, canvas.height);
  }
  //進行壓縮
  let ndata = canvas.toDataURL("image/jpeg", 0.3);
  tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
  return ndata;
 },

上傳

完成圖片壓縮后,就可以塞進formdata里進行上傳了,先將base64數據轉成字符串,再實例化一個ArrayBuffer,然后將字符串以8位整型的格式傳入ArrayBuffer,再通過BlobBuilder或者Blob對象,將8位整型的ArrayBuffer轉成二進制對象blob,再將blob轉為File對象

_upload(data, name, type) {
  let text = window.atob(data.split(",")[1]);
  let buffer = new ArrayBuffer(text.length);
  let ubuffer = new Uint8Array(buffer);
  let pecent = 0,
  loop = null;

  for (var i = 0; i < text.length; i++) {
  ubuffer[i] = text.charCodeAt(i);
  }

  let Builder =
  window.BlobBuilder ||
  window.WebKitBlobBuilder ||
  window.MozBlobBuilder ||
  window.MSBlobBuilder;
  let blob;
  if (Builder) {
  var builder = new Builder();
  builder.append(buffer);
  blob = builder.getBlob(type);
  } else {
  blob = new window.Blob([ubuffer], { type: type });
  }
  // blob 轉file
  var fileOfBlob = new File([blob], name, { type: type });
  return fileOfBlob;
 }
 }

將圖片壓縮上傳封裝到一個js文件里

const UploadImg = {
 imageHandle(files, maxSize, imgDom) {
  let that = this;
  let formdata = new FormData();
  let reader = new FileReader();
  reader.readAsDataURL(files[0]); //將圖片轉成base64格式
  //reader.onload是異步,要用到Promise對象將值返回出去
  return new Promise((resolved, rejected) => {
   reader.onload = function () {
    let result = this.result;
    let img = new Image();
    img.src = result;
    if (this.result.length <= maxSize) {
     imgDom.src = result;
     img = null;
     formdata.append("image", that._upload(result, files[0].name, files[0].type));
     resolved(formdata);
    } else {
     img.onload = function () {
      let data = that._compress(img);
      imgDom.src = data;
      formdata.append("image", that._upload(data, files[0].name, files[0].type));
      resolved(formdata);
     };
    }
   };
  })

 },
 _compress(img) {
  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext("2d");
  //瓦片
  let tCanvas = document.createElement("canvas");
  let tctx = tCanvas.getContext("2d");
  let width = img.width;
  let height = img.height;
  //如果圖片大于四百萬像素,計算壓縮比并將大小壓至400萬以下
  let ratio;
  if ((ratio = (width * height) / 4000000) > 1) {
   ratio = Math.sqrt(ratio);
   widht /= ratio;
   height /= ratio;
  } else {
   ratio = 1;
  }
  canvas.width = width;
  canvas.height = height;
  //鋪底色
  ctx.fillStyle = "#fff";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  //如果圖片像素大于100萬則使用瓦片繪制
  let count;
  if ((count = (width * height) / 1000000) > 1) {
   count = ~~(Math.sqrt(count) + 1); //計算要分成多少瓦片
   //計算每塊瓦片的寬高
   let nw = ~~(width / count);
   let nh = ~~(height / count);
   tCanvas.width = nw;
   tCanvas.height = nh;
   for (let i = 0; i < count; i++) {
    for (let 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, canvas.width, canvas.height);
  }
  //進行最小壓縮
  let ndata = canvas.toDataURL("image/jpeg", 0.3);
  tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
  return ndata;
 },
 _upload(data, name, type) {
  let text = window.atob(data.split(",")[1]);
  let buffer = new ArrayBuffer(text.length);
  let ubuffer = new Uint8Array(buffer);

  for (var i = 0; i < text.length; i++) {
   ubuffer[i] = text.charCodeAt(i);
  }

  let Builder =
   window.BlobBuilder ||
   window.WebKitBlobBuilder ||
   window.MozBlobBuilder ||
   window.MSBlobBuilder;
  let blob;
  if (Builder) {
   var builder = new Builder();
   builder.append(buffer);
   blob = builder.getBlob(type);
  } else {
   blob = new window.Blob([ubuffer], { type: type });
  }
  // blob 轉file
  var fileOfBlob = new File([blob], name, { type: type });
  return fileOfBlob;
 }
}

export default UploadImg

調用代碼

import UploadImg from "../../util/uploadImg";

methods: {
 imageHandle(e) {
  let maxSize = 100 * 1024;
  let imgDom = this.$refs.upImg;
  let files = e.srcElement.files;
  if (!files.length) return; //文件長度大于0
  if (!/^image\//.test(files[0].type)) return; //必須是圖片才處理
  if (!window.FileReader) return; //支持FileReader

  if (this.docEntry === "" || this.lineId === "") {
  this.$toast("請填寫完整信息", "error");
  return;
  }
  // let formdata = new FormData();
  UploadImg.imageHandle(files, maxSize, imgDom).then(formdata => {
  formdata.append("docEntry", this.docEntry);
  formdata.append("lineId", this.lineId);
  formdata.append("action", "ProductionListImage");
  this.$store
   .dispatch("uploadImage", formdata)
   .then(data => {
   if (data === 1) {
    this.$toast("上傳成功", "success");
   } else if (data === -1) {
    this.$toast("圖片為空", "error");
   } else {
    this.$toast("上傳失敗", "error");
   }
   })
   .catch(error => this.$toast("上傳失敗", "error"));
  });
 }
 }

參考鏈接:移動端利用H5實現壓縮圖片上傳功能

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

诸城市| 股票| 和顺县| 丹棱县| 垫江县| 虞城县| 休宁县| 文安县| 和田县| 开平市| 新余市| 延边| 乐至县| 松江区| 石屏县| 巴彦淖尔市| 额尔古纳市| 海兴县| 确山县| 大新县| 灵台县| 巴林右旗| 长汀县| 枣庄市| 麟游县| 墨脱县| 南华县| 蕉岭县| 当阳市| 海安县| 唐山市| 得荣县| 竹山县| 泽州县| 梅州市| 仙游县| 神木县| 缙云县| 小金县| 汾西县| 墨玉县|