天天看點

使用 canvas 繪制圖檔,然後下載下傳、上傳

最近做了個需求,設計提供幾張切圖。前端把切圖還有背景傳回的文本資訊,拼接到一塊繪制為一張圖檔。然後會下載下傳、或者上傳。 做起來其實還是挺簡單的。下面說下大概的流程。

前端繪圖隻能使用 canvas。

1、主要用到的canvas API 有以下幾個:

let cvs = document.createElement('canvas');
    let ctx = cvs.getContext('2d');
    // 設定填充顔色,也可以設定字型顔色
    ctx.fillStyle = bgcColor; 
    // 設定文本資訊。字型、大小、font-weight等。
    ctx.font = 'bold 20px 宋體'; 
    // 設定文本對齊方式
    ctx.textAlign = 'center'; // left || right || center || start || end; 總共五個值,常用left、center;
    // 設定文本基線對齊方式 類似于css的 vertical-align  
    ctx.textBaseLine = 'middle'; // top || hanging || middle || alphabetic || ideographic || bottom
    // 繪制文本  text: 文本内容。x: 文本的X坐标。y: 文本的Y坐标。maxWidth: 繪制文本的最大寬度。
    ctx.fillText(text, x, y, maxWidth);
    // 計算文本所占的寬度  這個方法傳回一個對象,有個 width 屬性。
    ctx.measureText(text)
    // 繪制矩形
    ctx.fillRect(0, 0, width, height);
    // 繪制圖檔 img: 目标圖檔。x: X坐标。y: Y坐标。width:繪制的寬度。height:繪制的高度。
    ctx.drawImg(img, x, y, width, height);
    // 繪制圓
    ctx.arc()
           

canvas的詳情參考 https://www.w3cplus.com/blog/tags/616.html

2、使用canvas 繪圖完畢後。提供導出下載下傳

canvas 有兩個API。可以把繪制的圖檔轉為可下載下傳的檔案。

canvas.toDataURL() 方法傳回一個包含圖檔展示的 dataURL。可以使用 type 參數設定類型。預設為 PNG 格式。圖檔的分辨率為 96dpi; 
 * 如果畫布的高度或寬度 為0 那麼會傳回字元串 “data:,”
 * 如果傳入的類型非"image/png",但是傳回的值以"data:image/png"開頭,那麼該類型是不支援的。
 * chrome 支援 "image/webp"類型
           

文法

canvas.toDataURL(type, encoderOptions);           

參數

type: 圖檔格式。預設為 image/png;
 encoderOptions: 在指定的格式為 'image/jpeg'、'image/webp'的情況下,可以設定從0 - 1 的值來改變圖檔的品質。
         如果超出取值範圍會設定為 0.92 。其他參數會忽略
           

傳回值

傳回一個 包含 dataURL 的 DOMString (也就是base64);           

如何下載下傳

// 下載下傳方法。
  /**
   *@param imgSrc 檔案連結可以是一個dataURL 也可以是一個 blob 對象。
   *@param imgName  下載下傳後的檔案名字。
  */
  function downloadImg (imgSrc, imgName) {
      let elem = document.createElement('a');
      elem.setAttribute('href', imgSrc);
      elem.setAttribute('download', imgName);
      document.body.appendChild(elem);
      elem.click();
      document.body.removeChild(elem);
  }
           

看了上面這些方法之後,這個需求就比較簡單了

let cvs = document.createElement('canvas');
  let ctx = cvs.getContext('2d');
  .....
  //圖檔繪制完成
  let imgSrc = ctx.toDataURL('image/jpeg', 0.9);
  let imgName = '測試圖檔.jpg';
  downloadImg(imgSrc, imgName); // 浏覽器就會自動下載下傳了
           

一開始,我用的就是上面這種方法下載下傳,不過當繪制下載下傳一個比較大的圖檔時,浏覽器就會提示下載下傳失敗。查了資料,原來使用dataURL進行下載下傳會有大小限制。後來再次查資料發現可以使用 blob 進行下載下傳。

關于blob的詳情請參考:https://developer.mozilla.org/zh-CN/docs/Web/API/Blob

了解一下,canvas 如何轉為 blob

canvas.toBlob(callback, type, encoderOption);            
callback:  因為canvas 如何轉為 blob是一個異步操作,是以需要一個回調函數,參數就是 blob對象。
type: 指定圖檔格式。預設為: 'image/png';
encoderOption: 在指定的格式為 'image/jpeg'、'image/webp'的情況下,可以設定從0 - 1 的值來改變圖檔的品質。
      如果超出取值範圍會設定為 0.92 。其他參數會忽略
           

這個方法沒有傳回值。

好了,現在看下如何使用 blob 進行下載下傳

let cvs = document.createElement('canvas');
 let ctx = cvs.getContext('2d'); 
 .....
 // 圖檔繪制完成
 ctx.toBlob(function (blob) {
     let imgSrc = window.URL.createObjectURL(blob);
     let imgName = '測試圖檔.jpg';
     downloadImg(imgSrc, imgName);
     window.URL.revokeObjectURL(imgSrc);
 }, 'image/jpeg', 0.9)
           

有兩個方法,之前沒有了解過,今天就記錄一下。\

URL.createObjectURL()

看到MDN上對這個方法的介紹,這是一個實驗中的功能,某些浏覽器尚在開發中。該标準對應的文檔可能被重新修訂,是以在未來版本的浏覽器中,該功能的文法和行為也可能改變。(這些東西,以後再說,現在是管不了那麼多了。都怪産品^_^)。

URL.createObjectURL()

靜态方法會建立一個

DOMString

,其中包含一個表示參數中給出的對象的URL。這個URL的生命周期和建立它的視窗中的

document

綁定。這個新的URL對象表示指定的

File

對象或

Blob

對象。

objectURL = URL.createObjectURL(blob);  // window可以省略           

用來建立URL的

File

Blob

注意事項

在每次調用

URL.createObjectURL(blob)

方法時,都會建立一個新的URL對象,盡管已經用相同的參數建立過。是以,當不再需要這個URL對象時,必須通過調用

URL.revokeObjectURL()

方法來釋放。浏覽器會在文檔退出的時候,釋放它們,不過為了獲得最佳使用性能以及記憶體狀況,你應該在安全的時機主動釋放它們。

URL.revokeObjectURL()

URL.revokeObjectURL()

靜态方法用來釋放一個之前通過調用

URL.createObjectURL(blob)

方法生成的URL對象。

window.URL.revokeObjectURL(objectUrl)           
objectUrl: URL.createObjectURL(blob)方法生成的URL對象;           

今天先記錄下如何下載下傳。明天記錄下如何上傳圖檔

原文釋出時間為:2018年06月22日

原文作者:要吃早餐

本文來源: 

掘金 https://juejin.im/entry/5b3a29f95188256228041f46

如需轉載請聯系原作者

繼續閱讀