需要将一个背景图+动态获取的微信名+微信头像拼接成一张图片,用户可长按保存最终图片,最终就是要将html转换成图片。
最初想自己用canvas画,但是有些麻烦,后来发现了html2canvas这个插件,先将html转成canvas,再生成图片。
因为生成的图片和html是在同一个页面中,最初想法是页面加载完成后,html内容隐藏,对应的图片盒子生成并显示,在实现过程中发现如果将html内容隐藏,图片会生成失败。
于是换一种思路,将html内容定位在页面底部,canvas生成的图片做一个层级遮罩,完美~
1、清晰度的问题:
网上有很多将教你设置canvas的scale,然后保存。我试图将倍数放到n倍,可是依然模糊,再此过程中,发现了类似的生成图片的库dom-to-image,结果更加的模糊到可怕,因为一开始的类库是从网上随意找了插件拿过来的版本,最后我尝试将html2canvas.js版本更新到最新版本(官网下载最新版本),问题得以解决。(另,在实现过程中发现如果图片作为background-image时,依然是有些模糊的,换成页面引入图片即可解决)
官网地址:
http://html2canvas.hertzen.com/
2、图片跨域问题:useCORS:true,allowTaint:false
设置 useCORS: true , 如果使用以上跨域方法, 若同时设置为 allowTaint: true , 会认为画布已被污染而不可用;
3、图片显示半截或者图片无法显示问题:
解决办法如下:
1)添加3000毫秒延迟加载,2)图片全部加载完成后,再调用生成图片方法,3)头部添加<meta http-equiv="Access-Control-Allow-Origin" content="yes">,4)给引入图片添加属性crossorigin="anonymous"(为后边的bug埋下了伏笔,巨坑!)
function takeScreenshot() {
setTimeout(function(){ //添加3000毫秒延迟,防止图片没有加载完成,就生成canvas,导致页面图片空白
html2canvas(document.querySelector("#posterHtml"),{useCORS:true,allowTaint:false}).then(canvas => {
var dataUrl = canvas.toDataURL();
console.log(canvas.style.width);
console.log(canvas.style.height);
// $("#posterImg").width(canvas.style.width).height(canvas.style.height)
document.getElementById("posterImg").children[0].src = dataUrl;
},1000);
$('#posterPrizeimg img').on('load', function() {
//图片加载完成 调用生成图片方法
takeScreenshot();
4、图片偶现问题!
这个问题困扰了我很久,图片偶现,既然会出现,肯定跟跨域没啥大的关系了,到底是什么原因呢,因为第二天要上线,尝试了各种办法未能得到解决,最终在大佬的一篇博客中得以解决,非常感激大佬的分享!
因为偶现的问题,我一直在删除之前的 crossorigin="anonymous"属性做各种尝试,结果发现之前手机完美展示的反而图片不显示,之前图片不显示的反而完美呈现?
-引用:原因跟html2canvas库的工作原理有很大的关系。如前文所说,html2canvas库需要我们先提供一段DOM节点,然后它再读取并解析这一段DOM节点生成canvas对象。如果DOM节点中已经使用了<img>标签的话,它也会解析这个<img>标签的src属性,然后重新创建一个Image对象,给它添加crossOrigin="anonymous"属性后尝试以跨域的方式重新读取图片数据。需要注意的是,一般CDN上的图片都是带有缓存响应头并且会在浏览器端缓存的,而且缓存的不仅仅是图片数据,还有HTTP响应头。所以问题的根本原因我们就找到了,当html2canvas尝试以跨域的方式去读取图片数据时,它读取到的是浏览器的缓存数据,而且因为我们没有给DOM节点中的<img>标签添加crossorigin="anonymous"属性,所以缓存数据是不带Access-Control-Allow-Origin响应头的,进而导致html2canvas库读取到的图片数据污染了生成的canvas对象,最终致使canvas导出数据报错。
事情是这样子的,如果你要用来生成canvas的dom中包含的<img>图片,之前已经被你的用户访问过(例如你是在对线上现有的业务进行改造),显然之前你应该没有给<img>标签添加crossorigin="anonymous"属性,那么请注意,这时候你的用户的浏览器已经把这些图片缓存在了本地,所以即便你按照上面的步骤都做了也没用,因为访问图片时读到的都是不带Access-Control-Allow-Origin等响应头的缓存数据。
这个时候你要做的,就是给要生成canvas的dom中的所有<img>标签的src添加一个任意的字符串,只要能起到重新发起图片读取请求,从而避免读取到浏览器缓存数据即可,如下所示:
'http://h0.hucdn.com/open/201819/9404b56f97e7df8a_750x1334.png?any_string_is_ok'
注意,不要添加随机字符串,那会击穿CDN缓存的,随便添加一个固定的字符串,能够避免读取到浏览器的缓存数据就可以了。这是本人血的教训!所以请大家千万千万不要忽视这一点!引用结束--
链接:https://www.jianshu.com/p/22bd5b98e38a
当我看完这断文字的时候,我就觉得真相终于找到了。
于是我在我的每张图片后边追加固定字符串,再次发版测试,完美解决~
需要将一个背景图+动态获取的微信名+微信头像拼接成一张图片,用户可长按保存最终图片,最终就是要将html转换成图片。最初想自己用canvas画,但是有些麻烦,后来发现了html2canvas这个插件,先将html转成canvas,再生成图片。因为生成的图片和html是在同一个页面中,最初想法是页面加载完成后,html内容隐藏,对应的图片盒子生成并显示,在实现过程中发现如果将html内容隐藏,...
html2canvas在ios15中出错的问题
设置
html2canvas的
字体样式可能会解决问题。
解决方案:font-family: “\9ED1\4F53”; (将
字体转成unicode码显示)
我
遇到的问题是使用
html2canvas签名上传到阿里云,但是在上传时会直接卡死页面并强制刷新,
然后在网上找到答案,估计是
html2canvas的
字体ios15不支持,改变设置了
html2canvas的div
字体样式有可能会解决问题,我是解决了。
解决方案: 需要截图的节点根样式添加font-variant: normal;
2. 文字向下偏移。
解决方案: 指定
html2canvas的版本号为1.0.0-alpha.12
3. 不完整,缺失,留白。
出现情况: 当截图区域超过视图高度,且滚动条未处在顶部时,会出现。
解决方案: 截图之前控制滚动条至顶部。
4. 模糊,不清晰。
出现情况: 通常是图片设置为背景的情况下,截图会比较模糊。
解决方案: 将背景图通过img标签加定位的方式实现。
今天在研究html2canvas截取页面的时候,发现截取后的图片没有把应该截取元素的背景图片截掉,背景图片空白。此时谷歌浏览器控制台报Failed to load resource: net::ERR_CACHE_MISS 和图片跨域的错误。
使用了useCORS: true后还是无法解决这个问题。于是就自己想办法,既然不同域名下的图片会有跨域问题,那么将图片转成base...
如何使用JS截取HTML页面为图片呢,下面为大家介绍一款JS截图插件html2canvas.js
html2canvas.js 能够实现在用户浏览器端直接对整个或部分页面进行截屏。
html2canvas.js可以将当页面渲染成一个Canvas图片,通过读取DOM并将不同的样式应用到这些元素上实现。
它不需要来自服务器任何渲染,整张图片都是在客户端浏览器创建。当
浏览器不支持Canvas时,将采用Flashcanvas或ExplorerCanvas技术代替实现。
以下浏览器能够很好的支持该脚本:Firefox 3.5+, Google Chrome, Opera新的版本, IE9以上的浏览器。
HTML2Canvas是一个流行的JavaScript库,可以在浏览器中将HTML元素转换为图像。它可以用于捕捉整个页面,也可以截取页面中的某一部分。但是,在使用HTML2Canvas来截取iframe时,有时会遇到截图空白的问题。
可能的原因有以下几种:
1.同源策略:如果iframe与父页面不在同一个域中,则由于浏览器的跨域限制,HTML2Canvas可能无法访问iframe中的内容,导致截图空白。
2.异步加载:如果iframe中的内容是异步加载的,HTML2Canvas可能在截图时无法捕捉到这些内容,因此产生截图空白的问题。
3.渲染问题:如果iframe中存在复杂的CSS样式或JavaScript代码,可能会导致HTML2Canvas无法正确渲染iframe中的内容,导致截图空白。
解决这些问题的方法有以下几种:
1.使用iframe转发:通过在iframe中添加一个转发脚本,将iframe的内容转发到父页面中,然后在父页面中使用HTML2Canvas来截取内容。
2.延迟加载:使用setInterval或setTimeout等方法,等待iframe中的内容全部加载完毕后再执行HTML2Canvas的截图操作。
3.使用HTML2Canvas的proxy选项:可以通过将proxy选项设置为true来解决同源策略的问题。这将使用后台代理来捕捉iframe中的内容,并将其转发到父页面中做截图处理。
总之,HTML2Canvas是一个非常有用的工具,可以让我们方便地将网页截图,但在截取iframe时需要特别注意上述问题。