記一次用html2canvas將頁面內容生成海報並儲存圖片到本地
阿新 • • 發佈:2021-07-27
將頁面內容儲存為圖片,一般採用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標籤的方式,但是會出現圖片模糊的情況,同時在微信瀏覽時有的手機機型還會識別不出生成的圖片,具體原因還未可知
注意點
allowTaint: true
和useCORS: true
都是解決跨域問題的方式,不同的是使用allowTaint
會對canvas造成汙染,導致無法使用canvas.toDataURL
方法,所以這裡不能使用allowTaint: true
- 在跨域的圖片裡設定
crossOrigin="anonymous"
並且需要給imageUrl
加上隨機數 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結構樣式放大一倍來設定,最後縮小一倍顯示在頁面中