1. 程式人生 > 其它 >記一次用html2canvas將頁面內容生成海報並儲存圖片到本地

記一次用html2canvas將頁面內容生成海報並儲存圖片到本地

將頁面內容儲存為圖片,一般採用html2canvas的方式,但是該方式存在一個問題,如果處理不好則生成的圖片會模糊不清晰,從jquery時就用過這個外掛,但是在Vue系列框架中還是第一次用,中途也遇到過很多問題,特此記錄。

由於是H5專案,並且要求使用uniapp,但是該方法在Vue等框架中也適用

<view class="on-court-poster" id="onCourtPoster">
    <!-- 頁面佈局僅供參考 -->
    <view>頁面需要生成圖片的內容</view>
    <!-- 用來儲存生成圖片 -->
    <image :src="prurl" alt="分享海報" id="posterIimg" class="poster-img" v-show="!hidden"/>
</view>

html2canvas外掛配置

import html2canvas from "html2canvas"

// 校正截圖不全問題
window.pageYoffset = 0;
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
const domObj = document.getElementById('需要生成圖片的內容外層的盒子id')
let width = domObj.offsetWidth; //獲取dom 寬度
let height = domObj.offsetHeight; //獲取dom 高度
let canvas = document.createElement("canvas"); //建立一個canvas節點
const scale = 2; //定義任意放大倍數 支援小數
canvas.width = width * scale; //定義canvas 寬度 * 縮放
canvas.height = height * scale; //定義canvas高度 *縮放
let context = canvas.getContext('2d');
// 【重要】關閉抗鋸齒
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
console.log('父元素寬度', width)
console.log('父元素高度',height)
let opts = {
    // 注意:  allowTaint: true  和 useCORS: true 不能同時設定,兩者只有一個起作用
          scale: scale, // 新增的scale 引數
          canvas: canvas, //自定義 canvas
          // allowTaint: true, // 允許汙染,允許畫布上有跨域圖片 不建議使用 後面詳細補充
          logging: true, //日誌開關,便於檢視html2canvas的內部執行流程
          width: width, //dom 原始寬度
          height: height,
          dpi:300,
          useCORS: true ,// 【重要】開啟跨域配置
          letterRendering: true,
        };
html2canvas(domObj, opts).then(canvas => {
    // 在微信裡,可長按儲存或轉發
    _this.prurl = canvas.toDataURL('image/png');
    let detail = document.getElementById('posterIimg') // 防止圖片url的標籤的id
    detail.style.width = canvas.width / 2 + "px";
    detail.style.height = canvas.height / 2 + "px";
    _this.hidden = false;
})

以上方法為最終成功的配置,之前採用過動態生成img標籤的方式,但是會出現圖片模糊的情況,同時在微信瀏覽時有的手機機型還會識別不出生成的圖片,具體原因還未可知

注意點

  1. allowTaint: trueuseCORS: true 都是解決跨域問題的方式,不同的是使用allowTaint 會對canvas造成汙染,導致無法使用canvas.toDataURL 方法,所以這裡不能使用allowTaint: true
  2. 在跨域的圖片裡設定 crossOrigin="anonymous" 並且需要給imageUrl加上隨機數
  3. canvas.toDataURL('image/jpg') 是將canvas轉成base64圖片格式。

1 生成圖片裁剪不完整
解決:將圖片 html 放在頁面根部,即相當直接放在 body 的內部

2 需要繪製的圖片跨域問題
解決: 1) 設定 useCORS: true, 使用跨域(當allowTaint為true時這段程式碼沒什麼用,下面解釋)
2) img圖片設定屬性 crossorigin="anonymous"

3 轉換base64不成功
解決:allowTaint: true 允許汙染,被汙染的 canvas 是沒法使用 toDataURL() 轉 base64 流的

4 圖片清晰度差
解決:html結構樣式放大一倍來設定,最後縮小一倍顯示在頁面中