將 Canvas 保存為圖片并下載至本地

在實(shí)際開發(fā)過程中,有時(shí)需要將圖表或者地圖等基于Canvas技術(shù)渲染的數(shù)據(jù)下載到本地保存到情況,下面介紹兩種方法來完成這種功能。

一、a 標(biāo)簽法

a 標(biāo)簽方法主要分為以下步驟:

  1. 將 canvas 元素的數(shù)據(jù)通過原生 api 轉(zhuǎn)換成 base64 編碼的圖片格式
  2. 利用 a 標(biāo)簽設(shè)置 download 屬性可以將 href 鏈接元素下載,我們將 a 標(biāo)簽的 href 屬性值設(shè)置為上一步獲得的 base64 格式字符串
  3. 構(gòu)造一個(gè)單擊事件并通過 api 觸發(fā) a 標(biāo)簽的 click 事件完成下載

注意點(diǎn):由于瀏覽器安全限制,事件觸發(fā)的代碼不能被異步代碼包裹


以下為代碼示例:

index.html

<!-- 待下載對(duì) canvas 元素 -->
<!-- 移動(dòng)端可能會(huì)由于 viewport 的原因?qū)е孪螺d的圖片不清晰,我們可以在 canvas 標(biāo)簽上直接設(shè)置 width 和 height 屬性,不采用 style 中的 width 和 height, 相當(dāng)于設(shè)置內(nèi)部分辨率 -->
<canvas id="chart" width="1920" height="1080"></canvas>

<!-- 觸發(fā)下載操作的按鈕 -->
<button onclick="download('#chart')">下載</button>

download.js

function download(selector) {
  // 通過 API 獲取目標(biāo) canvas 元素
  const canvas = document.querySelector(selector);

  // 創(chuàng)建一個(gè) a 標(biāo)簽,并設(shè)置 href 和 download 屬性
  const el = document.createElement('a');
  // 設(shè)置 href 為圖片經(jīng)過 base64 編碼后的字符串,默認(rèn)為 png 格式
  el.href = canvas.toDataURL();
  el.download = '文件名稱';
  
  // 創(chuàng)建一個(gè)點(diǎn)擊事件并對(duì) a 標(biāo)簽進(jìn)行觸發(fā)
  const event = new MouseEvent('click');
  el.dispatchEvent(event);
}

下面我們總結(jié)下 a 標(biāo)簽法的優(yōu)缺點(diǎn):

  1. 優(yōu)點(diǎn):只使用瀏覽器提供的原生 API 就能實(shí)現(xiàn)我們的需求。
  2. 缺點(diǎn):無法被異步代碼包裹,也就是包含 Ajax 請(qǐng)求的情況下代碼不生效。
  3. 缺點(diǎn):對(duì)于分辨率過高的 canvas, 我們生成的 dataURL 過長,超過瀏覽器限制,可能會(huì)導(dǎo)致無法順利下載,如出現(xiàn)此現(xiàn)象請(qǐng)參考下面介紹的方法。

二、saveAs 法

使用這種方法我們需要用到一個(gè)三方庫 FileSaver.js,該庫實(shí)現(xiàn)了 HTML5 規(guī)范中的 saveAs 方法。

該方法的主要步驟如下:

  1. 通過 canvas 的 toBlob API 將數(shù)據(jù)轉(zhuǎn)換為二進(jìn)制格式。
  2. 通過 FileSaver.js 提供的 saveAs 方法對(duì)該二進(jìn)制進(jìn)行下載。

下面是我們的實(shí)現(xiàn):

index.html

<!-- 通過 CDN 引入 FileSaver.js -->
<!-- 我們也可以通過 npm 引入 https://www.npmjs.com/package/file-saver
 -->
<script src="https://cdn.bootcss.com/FileSaver.js/1.3.8/FileSaver.min.js"></script>
<!-- 待下載對(duì) canvas 元素 -->
<canvas id="chart" width="1920" height="1080"></canvas>
<!-- 觸發(fā)下載操作的按鈕 -->
<button onclick="download('#chart')">下載</button>

download.js

function download(selector) {
  // 通過 API 獲取目標(biāo) canvas 元素
  const canvas = document.querySelector(selector);
  // 如果 toBlob 方法出現(xiàn)兼容性問題建議引入 https://github.com/eligrey/canvas-toBlob.js
  canvas.toBlob(function(blob) {
    saveAs(blob, '文件名稱')
  });
}

下面我們總結(jié)下 saveAs 法的優(yōu)缺點(diǎn):

  1. 優(yōu)點(diǎn):基本不限制下載圖片的大?。ú怀^本機(jī)內(nèi)存)
  2. 缺點(diǎn):需要引入第三方庫

三、涉及的資料

如果有不清楚的地方可以在評(píng)論中提出,我會(huì)及時(shí)作出解答,感謝閱讀!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容