html2canvas
当我们想生成一个海报的时候,最简单的方法是使用html2canvas(https://html2canvas.hertzen.com/)
使用这个库有两个需要注意的地方,一个是跨域(useCORS),一个清晰度(scale)。这两个都在它的配置闻到里有说明,就不细说了。
filter blur
今天要讨论的问题是这个库目前还没有实现的功能。* filter
就是如果我们的dom里使用了filter,比如我们想实现高斯模糊https://www.zhangxinxu.com/wordpress/2013/11/css-svg-image-blur/
在css里这样写:
.blur {
-webkit-filter: blur(10px); /* Chrome, Opera */
-moz-filter: blur(10px);
-ms-filter: blur(10px);
filter: blur(10px);
}
html2canvas目前没有实现这个功能,那就只能我们自己实现了。上面的链接里介绍了一个库http://www.quasimondo.com/StackBlurForCanvas/StackBlur.js
使用这个库,配合自己在canvas上绘制海报内容,就能生成带高斯模糊的图片。
具体需求
但是具体的需求有一个特别的地方,就是第一张图是用户看到的界面,但是用户长按保存的时候,实际下载的图片是第二张图的样子。
第一张图 第二张图
很显然我们需要有两个图层,一个背景模糊图层,和用户下载的图片图层,但是两个图层交界的地方看起来要无缝,就是一张图的感觉。这里的实现方式是把背景图片放到下载图层里,然后位置往上移动一定距离,使得和背景图层重合。这里具体实现的时候有一个细节,就是我在两个canvas里对同一图片分别使用StackBlur.js绘制出高斯后,两个图层没法完全重合,多少看起来中间有一条逢,最后的解决方案是先从背景canvas里导出高斯后的图片数据,然后使用putImageData把图片数据绘制到下载图层里,这样两个图层重复才是无缝的。这里猜想是因为两个canvas有一些细微差别导致的。
最后因为我们没有使用html2canvas这个库,所以自己绘制的canvas需要导出成图片数据,使用的 toDataURL
函数,这个函数有两个参数,第二个参数设置为1才能保证导出的质量最高。
当设置为1生成的图片还是模糊的时候,我们可以放大canvas的尺寸,来绘制高清图片,具体可以看这篇文章https://juejin.im/post/5bddac7d6fb9a049ee7fe452。
用户长按保存图片的小细节。因为用了两个图层,当用户长按到背景图层的时候,可能下载的是背景图层,这种情况如何使用用户长按任何位置都是下载的海报图层呢,我使用的方案是动态计算除去海报图层高度以后,上下到屏幕还有多少,有多少就设置多少padding,这样用户长按屏幕任意位置都会下载海报图层。
目前还有一个问题没有解决,就是在微信里长按的时候,因为图片上有二维码,所以是出现识别二维码的选项,对用户有一定干扰。
网友评论