亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

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

2019-11-19 12:18:02
字體:
來源:轉載
供稿:網友

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

主要用到filereader、canvas 以及 formdata 這三個h5的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實現壓縮圖片上傳功能

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色噜噜亚洲精品中文字幕| 日韩欧美在线一区| 全色精品综合影院| 91po在线观看91精品国产性色| 97超视频免费观看| 欧美在线观看www| 国产欧美日韩综合精品| 久久精彩免费视频| 亚洲第一精品夜夜躁人人躁| 久久久精品亚洲| 亚洲激情自拍图| 亚洲图片在区色| 亚洲美女精品成人在线视频| 久久久久久久亚洲精品| 91精品视频在线免费观看| 日韩视频永久免费观看| 欧美精品18videos性欧美| xxxxx91麻豆| 亚洲第一页中文字幕| 色999日韩欧美国产| 亚洲2020天天堂在线观看| 亚洲性av网站| 91在线观看免费| 日韩欧美在线第一页| 国产亚洲成av人片在线观看桃| 最新69国产成人精品视频免费| 亚洲福利影片在线| 午夜免费在线观看精品视频| 亚洲www在线观看| 一区二区三区国产在线观看| 最近免费中文字幕视频2019| 亚洲精品中文字幕av| 欧美激情女人20p| xxx欧美精品| 中日韩美女免费视频网站在线观看| 日韩在线观看免费| 国产成人一区二区三区电影| 久久精品国产96久久久香蕉| 国产精品永久免费视频| 在线播放日韩av| 国产成人亚洲综合| 欧美精品www| 亚洲奶大毛多的老太婆| 日韩中文字幕在线精品| 国产精品高潮粉嫩av| 97色在线播放视频| 久久精品一偷一偷国产| 国产精品免费看久久久香蕉| 久久视频这里只有精品| 亚洲欧美一区二区激情| 亚洲精品一区中文字幕乱码| 欧美日韩成人黄色| 国产极品jizzhd欧美| 国产精品精品久久久久久| 久久激情视频久久| 欧美电影免费观看电视剧大全| 深夜福利亚洲导航| 欧美日韩国产成人高清视频| 91中文在线视频| 国产午夜精品一区理论片飘花| 国产精品啪视频| 日韩国产精品一区| 亚洲999一在线观看www| 日韩在线高清视频| 日韩欧美视频一区二区三区| 日韩视频中文字幕| 亚洲精品久久久久中文字幕欢迎你| 成人h片在线播放免费网站| 91美女片黄在线观| 久久九九免费视频| 久久av中文字幕| 国产精品一区av| 韩国精品久久久999| 亚洲久久久久久久久久久| 中文字幕在线日韩| 久久福利网址导航| 在线看日韩欧美| 国产一区红桃视频| 亚洲精品福利资源站| 欧美电影免费观看大全| 日韩毛片在线看| 日韩av中文字幕在线播放| 一区二区三区在线播放欧美| 日韩成人在线播放| 欧美极品xxxx| 成年人精品视频| 久久精品国产亚洲7777| 韩国精品久久久999| 热久久视久久精品18亚洲精品| 国产精品视频久久久久| 日韩在线视频观看正片免费网站| 久久色精品视频| 一本色道久久综合狠狠躁篇的优点| 97免费视频在线播放| 日韩精品极品毛片系列视频| 中文字幕日韩欧美精品在线观看| 国产精品自拍网| 久久777国产线看观看精品| 日韩欧美中文字幕在线播放| 91成人精品网站| 成人中文字幕+乱码+中文字幕| 大荫蒂欧美视频另类xxxx| 国产精品视频导航| 岛国av一区二区三区| 韩剧1988在线观看免费完整版| 成人日韩av在线| 日韩一区二区在线视频| 日韩中文字幕精品视频| 久久久久久久久综合| 少妇av一区二区三区| 97香蕉超级碰碰久久免费的优势| 久久深夜福利免费观看| 国产精品露脸av在线| 欧美在线中文字幕| 国产精品1234| 亚洲激情国产精品| 久久免费视频这里只有精品| 欧美孕妇孕交黑巨大网站| 国产成人免费91av在线| 在线观看免费高清视频97| 日韩少妇与小伙激情| 国产成人精品久久二区二区| 性欧美xxxx| 欧美性xxxxx| 中文字幕国产亚洲2019| 色先锋资源久久综合5566| 欧美日韩免费区域视频在线观看| 亚洲综合最新在线| 亚洲国产高潮在线观看| 欧美亚洲在线视频| 欧美在线一级视频| 精品无码久久久久久国产| 一区二区成人精品| 乱亲女秽乱长久久久| 亚洲人成人99网站| 亚洲精品一区二区在线| 久久久久久久久亚洲| 亚洲成人av在线| 欧美精品在线观看| 国产亚洲欧美日韩美女| 91亚洲一区精品| 成人精品久久av网站| 国产成人精品免费视频| 久久久久国产一区二区三区| 欧美亚洲另类制服自拍| 欧美日韩亚洲视频| 国产精品美女999| 欧美电影免费在线观看| 中文字幕在线亚洲| 欧美疯狂性受xxxxx另类| 欧美日韩亚洲视频| 不卡av在线播放| 欧美大片免费观看在线观看网站推荐| 亚洲最大的av网站| 一本久久综合亚洲鲁鲁| 日韩在线中文字| 国外色69视频在线观看| 欧美理论在线观看| 色偷偷噜噜噜亚洲男人的天堂| 国产精品极品美女在线观看免费| 成人网在线视频| 欧美性xxxxx极品娇小| 国产精品久久久久久久电影| 欧美激情视频一区二区三区不卡|