整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          推薦!開箱即用的前端圖片壓縮方案(附源碼)

          推薦!開箱即用的前端圖片壓縮方案(附源碼)

          端實現圖片壓縮的背景

          我們都知道在“寸土寸金”的互聯網時代, 速度是第一競爭力, 雖然我們的5G發展已經搖搖領先, 但是也經不住用戶在一個網頁里傳很多“巨無霸”圖片, 最終導致的結果就是頁面“龜速”打開......

          那么作為技術人, 當然也有一堆的解決方案, 比如:

          • 壓縮圖片再上傳
          • 將圖片上傳到圖床, 利用圖床壓縮能力和CDN節點就近分發
          • 圖片流式加載
          • 圖片懶加載/ 預加載

          當然聰明的小伙伴也會將上面的方案組合, 設計更優秀的圖片“提速”方案.

          今天不會和大家把所有方案都介紹一遍, 因為網上也有很多實踐, 接下來會從前端技術提升的角度, 分享一下如何用原生 javascript, 實現從圖片上傳圖片自定義壓縮的完整方案. 大家可以把文章中介紹的方案直接用于自己的實際開發中, 或者基于它設計更棒的圖片壓縮方案.

          實現圖片壓縮的方案

          前端實現圖片壓縮無非就是在用戶上傳圖片文件后, 將file轉換成image對象, 然后再利用canvas 及其 api 將圖片壓縮成指定體積. 如下流程:

          代碼實現

          首先我們先實現將file轉換成image對象, 這里我們用到了FileReader API, 代碼如下:

          // 壓縮前將file轉換成img對象
          function readImg(file:File) {
              return new Promise((resolve, reject)=> {
               const img=new Image()
               const reader=new FileReader()
               reader.onload=function(e:any) {
                img.src=e.target.result
               }
               reader.onerror=function(e) {
                reject(e)
               }
               reader.readAsDataURL(file)
               img.onload=function() {
                resolve(img)
               }
               img.onerror=function(e) {
                reject(e)
               }
              })
          }
          

          這里使用 promise 來設計生成圖片數據的方法, 接下來我們看看核心的圖片壓縮源碼:

          /**
           * 壓縮圖片
           * @param img 被壓縮的img對象
           * @param type 壓縮后轉換的文件類型
           * @param mx 觸發壓縮的圖片最大寬度限制
           * @param mh 觸發壓縮的圖片最大高度限制
           * @param quality 圖片質量
           */
           function compressImg(img: any, type:string, mx: number, mh: number, quality:number=1) {
              return new Promise((resolve, reject)=> {
               const canvas=document.createElement('canvas')
               const context=canvas.getContext('2d')
               const { width: originWidth, height: originHeight }=img
               // 最大尺寸限制
               const maxWidth=mx
               const maxHeight=mh
               // 目標尺寸
               let targetWidth=originWidth
               let targetHeight=originHeight
               if (originWidth > maxWidth || originHeight > maxHeight) {
                if (originWidth / originHeight > 1) {
                 // 寬圖片
                 targetWidth=maxWidth
                 targetHeight=Math.round(maxWidth * (originHeight / originWidth))
                } else {
                 // 高圖片
                 targetHeight=maxHeight
                 targetWidth=Math.round(maxHeight * (originWidth / originHeight))
                }
               }
               canvas.width=targetWidth
               canvas.height=targetHeight
               context?.clearRect(0, 0, targetWidth, targetHeight)
               // 圖片繪制
               context?.drawImage(img, 0, 0, targetWidth, targetHeight)
               canvas.toBlob(function(blob) {
                resolve(blob)
               }, type || 'image/png', quality) 
              })
          }
          

          這里通過控制 canvas的寬高, 以及對 canvastoBlob設置參數, 來實現自定義的圖片壓縮.

          如果大家對代碼有不理解的地方, 也可以在文末發表問題, 我會做出對應的解答.

          更多前端提效方案

          • xijs 一款面向復雜業務場景的javascript工具庫
          • react-slider-vertify 基于react實現的滑動驗證碼組件
          • react-cropper-pro 支持圖片上傳+裁切+壓縮的組件
          • h5-dooring 在線H5頁面制作工具
          • v6.Dooring 可視化大屏搭建平臺


          的選擇是做或不做,但不做就永遠不會有機會。

          前言

          監聽剪切板粘貼事件,讀取剪切板中的圖片文件,轉成base64通過img標簽顯示出來,此時可能會存在剪切板中圖片過大,產生上傳速度慢問題,接下來就跟大家分享下如何將base64圖片進行壓縮。先跟大家展示下最終實現的效果:

          實現思路

          • 監聽剪切板粘貼事件
          • 從事件回調中獲取clipboardData中的image對象聲明一個變量接收該對象
          • 使用reader.readAsDataURL方法加載clipboardData中的image對象
          • 在reader.onload回調中獲取圖片base64碼
          • 創建Image對象,賦值圖片base64碼至當前對象的src屬性
          • 調用Image對象的onload函數,獲取圖片寬高等信息
          • 聲明canvas畫布寬高分別為當前圖片寬高除以縮放比例的值
          • 使用drawImage方法繪制當前圖片

          實現過程

          本篇文章主要講解剪切板圖片壓縮的實現,效果圖中如何將剪切板的圖片插入可編輯div以及如何發送,請移步我的另一篇文章:Vue解析剪切板圖片并實現發送功能

          • 監聽剪切板粘貼事件: 實現圖片粘貼
              const that=this;
              document.body.addEventListener('paste', function (event) {
                  that.$fullScreenLoading.show("讀取圖片中");
                  // 獲取當前輸入框內的文字
                  const oldText=that.$refs.msgInputContainer.textContent;
                  // 讀取圖片
                  let items=event.clipboardData && event.clipboardData.items;
                  let file=null;
                  if (items && items.length) {
                      // 檢索剪切板items
                      for (let i=0; i < items.length; i++) {
                          if (items[i].type.indexOf('image') !==-1) {
                              file=items[i].getAsFile();
                              break;
                          }
                      }
                  }
                  // 預覽圖片
                  const reader=new FileReader();
                  reader.onload=function(event) {
                      // 圖片內容
                      const imgContent=event.target.result;
                      // 創建img標簽
                      let img=document.createElement('img');//創建一個img
                      // 獲取當前base64圖片信息,計算當前圖片寬高以及壓縮比例
                      let imgObj=new Image();
                      let imgWidth="";
                      let imgHeight="";
                      let scale=1;
                      imgObj.src=imgContent;
                      imgObj.onload=function() {
                          // 計算img寬高
                          if(this.width<400){
                              imgWidth=this.width;
                              imgHeight=this.height;
                          }else{
                              // 輸入框圖片顯示縮小10倍
                              imgWidth=this.width/10;
                              imgHeight=this.height/10;
                              // 圖片寬度大于1920,圖片壓縮5倍
                              if(this.width>1920){
                                  // 真實比例縮小5倍
                                  scale=5;
                              }
                          }
                          // 設置可編輯div中圖片寬高
                          img.width=imgWidth;
                          img.height=imgHeight;
                          // 壓縮圖片,渲染頁面
                          that.compressPic(imgContent,scale,function (newBlob,newBase) {
                              // 刪除可編輯div中的圖片名稱
                              that.$refs.msgInputContainer.textContent=oldText;
                              img.src=newBase; //設置鏈接
                              // 圖片渲染
                              that.$refs.msgInputContainer.append(img);
                              that.$fullScreenLoading.hide();
                          });
                      };
                  };
                  reader.readAsDataURL(file);
              });
          
          • 實現base64圖片壓縮函數
                 // 參數: base64地址,壓縮比例,回調函數(返回壓縮后圖片的blob和base64)
              compressPic:function(base64, scale, callback){
                  const that=this;
                  let _img=new Image();
                  _img.src=base64;
                  _img.onload=function() {
                      let _canvas=document.createElement("canvas");
                      let w=this.width / scale;
                      let h=this.height / scale;
                      _canvas.setAttribute("width", w);
                      _canvas.setAttribute("height", h);
                      _canvas.getContext("2d").drawImage(this, 0, 0, w, h);
                      let base64=_canvas.toDataURL("image/jpeg");
                      // 當canvas對象的原型中沒有toBlob方法的時候,手動添加該方法
                      if (!HTMLCanvasElement.prototype.toBlob) {
                          Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
                              value: function (callback, type, quality) {
                                  let binStr=atob(this.toDataURL(type, quality).split(',')[1]),
                                      len=binStr.length,
                                      arr=new Uint8Array(len);
                                  for (let i=0; i < len; i++) {
                                      arr[i]=binStr.charCodeAt(i);
                                  }
                                  callback(new Blob([arr], {type: type || 'image/png'}));
                              }
                          });
                      }else{
                          _canvas.toBlob(function(blob) {
                              if(blob.size > 1024*1024){
                                  that.compressPic(base64, scale, callback);
                              }else{
                                  callback(blob, base64);
                              }
                          }, "image/jpeg");
                      }
                  }
              }
          

          github: https://github.com/likaia/chat-system/blob/master/src/components/message-display.vue

          作者:神奇的程序員K

          轉發鏈接:https://mp.weixin.qq.com/s/hADXM37cactAGFf2vduQJw

          實現 HTML 壓縮,可以使用 JavaScript 中的正則表達式來去除 HTML 中的空格和注釋。以下是一個簡單的 HTML 壓縮函數:

          function compressHTML(html) {
            // 去除注釋
            html=html.replace(/<!--[\s\S]*?-->/g, "");
            // 去除多余空白
            html=html.replace(/\s+/g, " ");
            // 去除標簽之間空格
            html=html.replace(/>\s+</g, "><");
            return html.trim();
          }

          該函數首先使用正則表達式去除 HTML 中的注釋。然后,它使用另一個正則表達式去除 HTML 中的多余空格。最后,它使用另一個正則表達式去除標簽之間的空格。

          為了測試該函數,您可以創建一個 HTML 文件,并在其中添加一些冗余的空格和注釋。例如:

          <!DOCTYPE html>
          <html>
            <head>
              <title>My Website</title>
            </head>
            <body>
              <!-- This is a comment -->
              <h1> Welcome to my website! </h1>
              <p> This is some text. </p>
            </body>
          </html>

          然后,您可以在Node.JS中使用以下代碼將 HTML 文件加載為字符串并壓縮它:

          // 加載 HTML 文件
          const fs=require("fs");
          const html=fs.readFileSync("index.html", "utf8");
          // 壓縮 HTML
          const compressedHtml=compressHTML(html);
          console.log(compressedHtml);

          輸出是一個壓縮后的 HTML 字符串,其中不包含注釋或冗余空格。

          或者直接在IE中測試,代碼如下:

          function compressHTML(html) {
            // 去除注釋
            html=html.replace(/<!--[\s\S]*?-->/g, "");
            // 去除多余空白
            html=html.replace(/\s+/g, " ");
            // 去除標簽之間空格
            html=html.replace(/>\s+</g, "><");
            return html.trim();
          }
          var html=`
          <!DOCTYPE html>
          <html>
            <head>
              <title>My Website</title>
            </head>
            <body>
              <!-- This is a comment -->
              <h1> Welcome to my website! </h1>
              <p> This is some text. </p>
            </body>
          </html>
          `;
          console.log(compressHTML(html));

          運行效果:


          主站蜘蛛池模板: 天天爽夜夜爽人人爽一区二区 | 国产日韩一区二区三区在线观看 | 色视频综合无码一区二区三区 | 制服丝袜一区在线| 中文字幕无码一区二区免费| 亚洲熟女www一区二区三区| 无遮挡免费一区二区三区| 一区二区三区精品高清视频免费在线播放 | 国产精品自拍一区| 亚洲欧美国产国产一区二区三区 | 色妞色视频一区二区三区四区| 中文字幕精品一区影音先锋 | 国产一区二区三区在线免费| 亚洲综合无码AV一区二区| 制服美女视频一区| av一区二区三区人妻少妇| 国产一区在线mmai| 国产成人综合一区精品| 精品无码一区二区三区爱欲| 国产一区韩国女主播| 国产精品一区二区久久精品涩爱| 任你躁国产自任一区二区三区| 国产一区二区三区在线观看精品| 日韩一区二区免费视频| 亚洲国产成人久久一区二区三区 | 一区二区三区四区免费视频| 精品人妻中文av一区二区三区| 国产精品无圣光一区二区 | 一区二区三区免费电影| 国产成人精品一区二三区熟女 | 国产伦精品一区二区三区视频猫咪 | 精品乱人伦一区二区三区| 国内精品视频一区二区三区八戒| 国产美女精品一区二区三区| 国产一区二区三区夜色| 一区二区三区视频观看| 国产精品 视频一区 二区三区| 日韩在线视频一区二区三区| 国产精品一区在线观看你懂的| 无码一区二区三区免费| 无码乱人伦一区二区亚洲一|