1. 程式人生 > 其它 >前端開發系列029-基礎篇之Canvas繪圖(壓縮)

前端開發系列029-基礎篇之Canvas繪圖(壓縮)

title: '前端開發系列029-基礎篇之Canvas繪圖(壓縮)'
tags:
  - javaScript系列
categories: []
date: 2017-07-28 08:20:13

寫這篇文章的原因是因為今天早上的時候,突然遇到個需求需要等比例調整照片的大小(主要是想把圖片等比例的縮小),我在Mac上通過圖片處理軟體搗鼓的時候發現比較麻煩,就隨手百度了一個線上修改圖片尺寸的網站,叫做[改圖寶](http://www.gaitubao.com/)。這個網站提供給圖片加logo、修改圖片尺寸以及印章製作等諸多功能,介面簡潔使用方便解決了我的問題,值得推薦。

然而,等到中午的時候,我發現還有一張圖片需要處理,恰好電腦連不上網路,我就考慮能不能通過程式碼自己來實現,因為圖片的選擇 - 壓縮 - 上傳

在實際開發中也是對應的場景,因此本文將介紹如何利用Canvas畫布來對圖片進行壓縮的技術,包括實現思路和具體的程式碼。

實現思路

[ 1 ] 獲取源影象資料

在頁面中我們使用input標籤(file型別)來讓使用者選擇對應的檔案上傳。為了等比例的對圖片進行壓縮,需要獲取源圖片的寬度和高度等資料引數,這裡使用了FileReader建構函式(類)。

具體實現的時候,先呼叫new FileReader()建立一個FileReader的例項物件,然後為input標籤註冊change事件監聽。當用戶選擇好檔案後,需要先檢查是否是圖片(通過MIMEType型別判斷),再通過FileReader例項來呼叫readAsDataURL(file)

方法來讀取圖片檔案的資料資訊,以獲取源圖片檔案的寬度和高度資訊。

[ 2 ] 計算寬高壓縮比資料

因為示例程式碼中演示的等比例的進行縮放(壓縮),因此需要通過得到目標圖片的寬度和高度尺寸資料。
這裡列出計算部分的核心程式碼

      var targetWidth,targetHeight;
      var imgWidth = img.width, imgHeight = img.height;
      var maxWidth = 150, maxHeight = 150;

      // 如果圖片尺寸超過限制,那麼需要重新計算寬高
      if (imgWidth > maxWidth || imgHeight > maxHeight) {

        if (imgWidth / imgHeight >= 1) {
          // 如果更寬,那麼就按照寬度限定尺寸
          targetWidth = maxWidth;
          targetHeight = Math.round(maxWidth * (imgHeight / imgWidth));
        } else {
          // 如果更高,那麼就按照高度限定尺寸
          targetHeight = maxHeight;
          targetWidth = Math.round(maxHeight * (imgWidth / imgHeight));
        }
      }

[ 3 ] 繪製目標圖片

當目標圖片(壓縮後)的寬高都計算完成後,可以通過Canvas上下文的drawImage方法來完成圖片的繪製,該方法的具體使用可以參考[ javaScript系列 [14]-Canvas繪圖(影象)](http://wendingding.com/2019/02/05/javaScript系列 [14]-Canvas繪圖(影象)這篇文章。

drawImage方法的第一個引數為需要繪製的圖片資料,該圖片資料即為使用者通過input標籤選擇的檔案內容。當然,在具體實現的時候還需要讀取檔案的內容,監聽載入完畢之後再設定Image資料來源。

  reader.onload = function(event) {
    /e.target.result是圖片的base64地址資訊
    img.src = event.target.result;
  }
完整程式碼
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<input type="file" id="file">
<div id="info" style="font-size: 13px"></div>
<canvas id="canvas" height="200" width="200"></canvas>
<script>

  //[1] 獲取頁面中的檔案選擇標籤
  var oInput  = document.querySelector('#file');

  //[2] 建立FileReader物件用於讀取檔案資訊
  var reader = new FileReader();
  var file   = null;  //檔案物件

  //[3] 給檔案選擇標籤新增事件監聽
  oInput.addEventListener('change', function (event) {

    //001 獲取使用者選擇的檔案
    file = event.target.files[0];

    //002 獲取檔案的MIMEType型別
    var fileType = file.type;

    //003 檢查使用者選擇的檔案是否是圖片
    if (fileType.indexOf("image") == 0) {

      //004 如果發現檔案是圖片則讀取圖片為DataURL
      reader.readAsDataURL(file);
    }
  });

  //[4] 建立Image影象例項
  var img  = new Image();
  var targetWidth,targetHeight;

  //[5] 監聽FileReader物件是否處理完畢,設定影象例項的資料來源
  reader.onload = function(event) {

    //說明:e.target.result是圖片的base64地址資訊
    img.src = event.target.result;
  }

    //[6] 監聽Image例項載入,壓縮圖片並生成預覽影象
    img.onload = function () {

      setFileInfo();

      //[7]在頁面中建立canvas畫布對圖片進行縮放(壓縮)後繪製
      var canvas = document.getElementById("canvas");
      var ctx = canvas.getContext("2d");
      ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
      ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
    }

    function setFileInfo() {
      // 獲取檔案的名稱
      var fileName = file.name;

      // 獲取檔案的大小
      var fileSize = (file.size / 1024 / 1024).toFixed(3) + "M";

      // 圖片壓縮比計算
      var imgWidth = img.width, imgHeight = img.height;
      var maxWidth = 150, maxHeight = 150;

      // 如果圖片尺寸超過限制,那麼需要重新計算寬高
      if (imgWidth > maxWidth || imgHeight > maxHeight) {

        if (imgWidth / imgHeight >= 1) {
          // 如果更寬,那麼就按照寬度限定尺寸
          targetWidth = maxWidth;
          targetHeight = Math.round(maxWidth * (imgHeight / imgWidth));
        } else {
          // 如果更高,那麼就按照高度限定尺寸
          targetHeight = maxHeight;
          targetWidth = Math.round(maxHeight * (imgWidth / imgHeight));
        }

        //在頁面中顯示圖片資訊
        var html = "<div>1.已選擇圖片" + fileName + ",大小為" + fileSize + "。</div>\n" +
            "<div>2.圖片原尺寸是:" + imgWidth + " x " + imgHeight + "</div>\n" +
            "<div>3.圖片壓縮尺寸:" + maxWidth + " x " + maxHeight + "</div>\n" +
            "<div>4.圖片已壓縮為:" + targetWidth + " x " + targetHeight +"</div>\n";

        var oDiv = document.getElementById("info");
        oDiv.innerHTML = html;
      }
    };

</script>
</body>
</html>
演示效果