php 抓取网页生成图片(css不能直接由前端生成分享快照呢?(图))
优采云 发布时间: 2021-11-24 15:14php 抓取网页生成图片(css不能直接由前端生成分享快照呢?(图))
欢迎关注富途web开发团队,php,前端需要你。Javascript
以前,一些朋友经常在微信中分享带有页面信息(分享图片)的图片。这种分享方式比通常的结构化分享(连接分享)更容易表达页面的内容。公司童鞋还想在活动页面生成分享图片(带有用户专属二维码),引导用户分享和传播。php
刚开始做这个功能的时候,我们从后台根据用户的信息生成了一张专属的分享图片,把图片上传到图片库,获取图片连接;然后前端调用接口获取共享图片的连接。页面使用img标签来展示这张图片,并附有一些引导文案,提醒用户“长按保存分享”。但是考虑到服务器压力、存储等问题,我们只会为一个用户执行一次生成共享图片的操作(当用户再次获取共享图片时,返回的图片是第一张生成的图片),即整个活动期间,单个用户生成的分享图片内容不会改变。通过这种方式,一些动态变化的数据无法在共享图片中显示,共享图片中可以显示的内容受到很大限制。css
后来,我们想知道前端是否可以直接生成这个共享快照?前端生成图片无需网络传输等操作,可以降低服务压力,并且每次都可以动态生成图片,让分享的图片可以展示一些随着用户操作不断变化的数据。以后发现已经有一些html的库可以生成canvas或者img了,我们来试试看,能不能直接从前端生成和分享快照。html
简单的想法
html转图片,(或者dom转canvas再转图片),把生成的图片的连接(多为base64)放在页面img元素的src属性上,然后给出相关的引导操作提示(例如:长按保存图片),引导用户分享/保存图片。前端
您提到的将 html 转换为画布或图像有两个主要库:java
演示测试
简单的例子安卓
html代码主要包括童鞋设计给出的共享快照原稿重构的共享快照html代码,以及生成图像的img容器。ios
我是html!!
我是dom-to-image生成的图片
我是html2canvas生成的图片
复制代码
在js代码中,主要是调用两个库的API生成图片或者canvas。nginx
// $snapshot为分享快照内容的dom元素,
// $snapshotImg为要放domtoimage生成的图片的img元素
// $snapshotImg2为要放html2canvas生成的图片的img元素
var $snapshot = document.querySelector('.j_snapshot');
var $snapshotImg = document.querySelector('.j_snapshot_img');
var $snapshotImg2 = document.querySelector('.j_snapshot_img2');
// domtoimage生成jpg的方法(这个库还有其余的方法)
domtoimage.toJpeg($snapshot,{
quality: 1
}).then(function (dataUrl) {
// 直接生成了base64的url
$snapshotImg.src = dataUrl;
}).catch(function (error) {
console.error('oops, something went wrong!', error);
});
// html2canvas 生成canvas
html2canvas($snapshot,{
// useCORS: true, // 容许图片跨域
backgroundColor: null,
logging: false,
}).then(function(canvas) {
// 'image/jpeg', 1.0
// 再利用canvas的toDataURL 方法,将canvas转为图片
var dataURL = canvas.toDataURL();
$snapshotImg2.src = dataURL;
}, function(err) {
console.error('oops, something went wrong!', err);
});
复制代码
以上...git
从上面六张图可以看出
所以~,还是用html2canvas吧。
遇到的问题
但是在使用html2canvas生成和分享图片的时候,还是存在一些问题,这里列举一些。
刚开始使用html/css重构和分享快照时,我们使用纯文本、img标签图片、css背景图片,以及图片/文本的放大和缩小。
第一次生成的图片没有达到预期效果,生成的图片效果和原图相差很大。你只能一一调查,发现问题,解决问题。
1. 跨域图片无法显示
我们的图片资源是基于CDN的,导致图片的链接域名和网页的域名不一致,造成跨域问题,可能导致图片无法显示。
解决:
第一步:将html2canvas的参数设置中的useCORS属性改为true,使html2canvas接受和处理跨域资源。
第二步:使图片资源允许跨域(在响应头中添加Access-Control-Allow-Origin:*)
这样就可以显示跨域图片了~
第三方跨域图像处理:
图片允许跨域还是比较容易的,但是如果使用了不允许跨域的第三方图片(比如微信头像),这个时候我们需要做更多的处理,让那个图片可以允许. 跨域....
看别人的方法是在服务器上实现第三方图片的代理(把第三方图片的域名改成自己的域名),然后让自己域名的资源允许跨领域。
为一个事件修改服务器的nginx配置不好吗?(*敏*感*词*=.=)。
所以我们在我们的活动中换了另一种方式。
后端不直接返回微信头像,而是一个可以对应相关微信头像的连接(这个连接的资源允许跨域)。后端收到本次连接请求后,会拉取微信头像信息返回给前端。头像的图片信息。【这里的backend是指activity中的backend代码,和上面改nginx配置不一样】
后来发现拉微信头像的操作有时会超时,于是又做了一层处理。首次获取微信头像后,将头像上传到自己的图片库(异步操作),然后访问页面,当需要微信头像时,会返回图片库中的图片链接(异步操作)当然,这个图片库连接也可以跨域)。
2.生成的共享图片不清晰
这里的不明确是指两个方面:
整个共享图像的清晰度还不够。生成的分享图片中原分享页面的图片不够清晰。
整个共享图像清晰度不够的问题的解决方法:
这里锐度不足的问题是由于图片的实际物理像素不够。这里的个人处理方法是修改html2canvas的scale属性,增加绘制时的缩放比例,从而提高锐度
html2canvas($snapshot, {
useCORS: true,
scale: window.devicePixelRatio*2 // 默认值是window.devicePixelRatio
backgroundColor: null,
logging: false
});
复制代码
原分享页面图片不够清晰,生成图片解决问题
我们使用两种方式在分享页面展示图片:
使用img标签元素来介绍图片 使用元素中的背景图片来介绍图片
但是从实际生成的图片效果来看,页面中使用背景图片的部分在共享快照中会特别不清晰,背景图片底部会出现一些没有的小刺在原页面(下图背景)中,生成的图片中富途标志下方有一条类似的细白线,但在原页面中没有)。
但是,在这种情况下不存在使用 img 标签元素来引入图像。
从图中可以看出,两张图片的页面截图(图片的上半部分)在清晰度上差别很小,但是图片经过html2canvs生成后,很明显背景图片中的图片有定义差异很大。,而且周围还有一些小人渣。
so:如果分享快照中使用图片,则尽量使用img标签代替背景图片,以保证分享图片的清晰度。
共享图像页面中的精灵图像
重构共享图片页面时,里面有一个vs内容。里面的阵营图片会根据用户的阵营选择和最终获胜阵营的结果显示不同的内容。我们为页面的性能开发了一些内容。方便的将这些营地图片放到精灵图片中,通过类控件展示不同的图片。
一开始没想到怎么用img元素来显示Sprite图片,但是还是用背景图片来展示阵营选择的内容。后来不时被吐槽产品童鞋分享那部分图片内容太模糊了.....
后来想了想,如果用Sprite图片,也可以用img标签来显示:
.emoji{ width: 10px; height: 10px; /*固定大小,超过的隐藏*/ overflow: hidden; display: block; position: relative; } .emoji.emoji01 img{ position: absolute; /*使用top,left 偏移img图片使之展现对应的位置*/ top: 0; left: -20px; }
复制代码
3.img 图像与变换属性不太兼容
在html2canvas的官方文档中,有一些css属性不是很兼容,大家自己测试一下。对于不能支持的属性,可以改一下写法~。
活动中遇到的就是img元素中transform的实现不是很好。
在示例中,我们希望图像居中,因此我们将以下 css 添加到 img 元素:
img{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 100%;
}
复制代码
但实际上,效果是这样的......
总结
使用html2canvas,通过将页面元素转换成图片来生成分享快照是可行的,但是在重构分享图片页面时,尽量使用常用的方法和css属性,少用背景图片生成一张。好分辨率的图片~。
原文:futu.im/article/cre...
添加一名作者