需求:將html轉成圖片並保存下來
問題:
- 不能畫圓角;
- 圖片模糊;
- 圖片跨域;
- 圖片顯示不出來;
- 不能使用省略號;
- 圖片生成偶爾失敗;
- 如何將圖片轉成文件流,上傳
接下來,我一個個闡述一下如何解決這些問題
問題1:
主要是使用overflow:hidden,在外邊框加上border-radius即可
問題2:
圖片模糊,可以將圖片格式設置成jpeg的,同時擴大scale 的倍數,這樣就可以解決了
問題3:
跨域這個搗鼓了好久,最後 還是讓後端來允許跨域了,但是這裏前端也需要設置兩個地方:
1)設置useCORS:true, allowTaint: false
2)img元素裏面設置跨域:crossOrigin = ‘anonymous’
問題4:
圖片顯示不出來有兩個原因
1) 跨域導致的,解決方案還是讓後端允許跨域,另外img 裏面也要設置crossOrigin = ‘anonymous’
2)將img 包裝過後,最好使用img 來直接顯示圖片(我之前就用包裝過的img,然後圖片有時候能顯示,有時候顯示不出來)
問題5:
html2Canvas 就是不支持多行超出顯示省略號,這裏有兩個方案
1)超出高度之後,直接overflow:hidden
2) js控制字數,截取
問題6:
將dom 元素轉成base64 之後,顯示在img裏,在這個轉化的過程中,可以使用setTimeout ,將時間設置1000ms或者500ms,這樣就可以解決
問題7:
這個百度裏面有好多,我這裏就粘貼一下代碼,自測有效
const base64ToBlob = function(base64Data, filename) {
const arr = base64Data.split(',');
const fileType = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let l = bstr.length;
const u8Arr = new Uint8Array(l);
while (l--) {
u8Arr[l] = bstr.charCodeAt(l);
}
return new File([u8Arr], filename, {type:fileType})
};
const file = base64ToBlob(base64Data, 'test.jpeg');
下面是全部的源代碼:
import React from 'react';
import html2canvas from 'html2canvas';
import {Toast} from 'antd-mobile';
// 具體option值可以查看文檔:http://html2canvas.hertzen.com/configuration
export function CreateImg(ele, newEle, hasNewImg){
try {
if(!ele) {
Toast.info('生成圖片內容不能爲空');
return ;
}
html2canvas(ele, {
scale: 4, // 這一塊的倍數先設置4。小程序是6
useCORS:true,
allowTaint: false,
logging:false,
// taintTest: false,
}).then(function(canvas) {
const base64Data = canvas.toDataURL('image/jpeg',1.0);
const newImg = new Image();
newImg.src = base64Data;
newImg.style.width = '3.74rem'; // 圖片寬度
newImg.style.height = '6.16rem'; // 圖片高度
newImg.crossOrigin = 'anonymous';
newEle.appendChild(newImg);
ele.style.display = 'none';
if(base64Data) {
hasNewImg(true);
}
// 將圖片轉成file : base64-> blob -> file 繞道轉主要是爲了兼容ios
// base64轉blob
// const base64ToBlob = function(base64Data, filename) {
// const arr = base64Data.split(',');
// const fileType = arr[0].match(/:(.*?);/)[1];
// const bstr = atob(arr[1]);
// let l = bstr.length;
// const u8Arr = new Uint8Array(l);
// while (l--) {
// u8Arr[l] = bstr.charCodeAt(l);
// }
// return new File([u8Arr], filename, {type:fileType}); // 直接轉成file 格式
// };
// const file = base64ToBlob(base64Data, 'test.jpeg');
// if(getFile){
// getFile(file);
// }
});
} catch (error) {
console.log('error:',error);
Toast.fail('圖片生成失敗');
}
}
// 在外部調用的時候使用
setTimeout(() => {
CreateImg(this.imgBox, this.newImg, this.hasNewImg);
},500);