需求:将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);