JS—圖片壓縮上傳(單張)

Inthur發表於2018-08-13

*vue+webpack環境,這裡的that指到vue例項

<input type="file" name="file" accept="image/*" @change="selectImgs" ref="file" />

一、圖片壓縮

    /*
        file:檔案(型別是圖片格式),
        obj:檔案壓縮後物件width, height, quality(0-1)
        callback:容器或者回撥函式
    */
    photoCompress(file,obj,callback){
        let that=this;
        let ready=new FileReader();
        /*開始讀取指定File物件中的內容. 讀取操作完成時,返回一個URL格式的字串.*/
        ready.readAsDataURL(file);
        ready.onload=function(){
            let re=this.result;
            that.canvasDataURL(re,obj,callback)  //開始壓縮
        }
    },
/*利用canvas資料化圖片進行壓縮*/
/*圖片轉base64*/
    canvasDataURL(path, obj, callback){
        
        let img = new Image();
        img.src = path;
        img.onload = function(){
            let that = this;   //指到img
            // 預設按比例壓縮
            let w = that.width,
                h = that.height,
                scale = w / h;
            w = obj.width || w;
            h = obj.height || (w / scale);
            let quality = 0.7;  // 預設圖片質量為0.7
            //生成canvas
            let canvas = document.createElement(`canvas`);
            let ctx = canvas.getContext(`2d`);
            // 建立屬性節點
            let anw = document.createAttribute("width");
            anw.nodeValue = w;
            let anh = document.createAttribute("height");
            anh.nodeValue = h;
            canvas.setAttributeNode(anw);
            canvas.setAttributeNode(anh);
            ctx.drawImage(that, 0, 0, w, h);
            // 影像質量
            if(obj.quality && obj.quality <= 1 && obj.quality > 0){
                quality = obj.quality;
            }
            // quality值越小,所繪製出的影像越模糊
            let base64 = canvas.toDataURL(`image/jpeg`, quality);
            // 回撥函式返回base64的值
            callback(base64);
        }
    },

二、base64轉檔案

這裡後臺介面不支援base64,根據實際介面情況使用

    /*這裡轉blob*/
    base64UrlToBlob(urlData){
        let arr = urlData.split(`,`), 
        mime = arr[0].match(/:(.*?);/)[1],  // 去掉url的頭,並轉化為byte
        bstr = atob(arr[1]),    // 處理異常,將ascii碼小於0的轉換為大於0
        n = bstr.length, 
        u8arr = new Uint8Array(n);
        while(n--){
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], {type:mime});
        //轉file
        //return new File([u8arr], filename, {type:mime});
    },

三、上傳圖片

    selectImgs(e) {    //選擇檔案後執行
      let that=this
      let fileObj=e.target.files[0]  //獲取file
      //console.log(fileObj)
      var form = new FormData();  // 建立FormData 物件
      if(fileObj.size/1024 > 1025) { //檔案大於1M(根據需求更改),進行壓縮上傳
          that.photoCompress(fileObj, {   //呼叫壓縮圖片方法
              quality: 0.2
          }, function(base64Codes){
              //console.log("壓縮後:" + base.length / 1024 + " " + base);
              let bl = that.base64UrlToBlob(base64Codes);
              //console.log(bl)
              form.append("file", bl, "file_"+Date.parse(new Date())+".jpg"); // 檔案物件
              that.imgRequest(form);  //請求圖片上傳介面
          });
      }else{ //小於等於1M 原圖上傳
          form.append("file", fileObj); // 檔案物件
          that.imgRequest(form);   //請求圖片上傳介面
      }
    },
     /*圖片上傳介面*/
    imgRequest(param){
      PostSaveImg(    //封裝的ajax(axios)方法
          param
      ).then(data => {
          if (data.status === 200 || data.status === 304){
            let item={
              path:this.imgpath+data.data[0].path,
            }
            let jsonitem={
              jlid:this.jlid,
              path:data.data[0].path,
              xxdm:this.xxdm,
            }
            this.imglistJson.push(jsonitem)
            this.imglist.push(item)
          }else{
             Toast({    //封裝的提示方法
                message: `圖片上傳失敗`,
                position: `middle`,
                duration: 2000
              })
          } 
      })
      
      /*原生請求*/
      // const xhr = new XMLHttpRequest()   
      // xhr.open(`POST`, HOSTMOBILE+`api/mobile/xcjg/sctp`, true)   //介面地址
      // xhr.send(param)
      //  xhr.onload = () => {
      //   if (xhr.status === 200 || xhr.status === 304) {
      //     let datas = JSON.parse(xhr.responseText)
      //     console.log(`response: `, datas)
      //   } else {
      //     alert(`${xhr.status} 請求錯誤!`)
      //   }
      // }
      
    },

其他

element ui 圖片上傳元件(不包含壓縮)

相關文章