H5 中html 页面存为图片并长按 保存

最近接到的一个新需求:页面一个静态H5,中间有一页是输入信息,而后跳转到最后一页,自动将页面生成图片,用户能够长按图片保存到手机上。

展现一下最后一页的样子:html

 

刚拿到这个需求,在网上看了不少文章,最广泛的是使用 html2canvas + canvas2image  来实现。因而,跟着前人的脚步,踏上了一个不断采坑采坑采坑的旅程。ios

下面直接描述我在作这个需求过程当中遇到的问题以及解决办法吧:canvas

1.html2canvas 图片跨域:

这个问题网上不少解决办法:跨域

这个是最经常使用的, 刚开始我只是加了红色框里面的这一句,可是并无任何做用,依旧报错。后来看到有人说,加上前面那一句,因此果断在加进去。浏览器

这两句其实表达的是同一个意思:容许图片跨域。缓存

固然,也有网友说,直接给一个空值就能够,我当时试了一下,并不ok~~~~.服务器

 

 

2.屡次使用canvas drawImage 方法图片展现问题

2.1 图片加载顺序问题

在我这个需求里面,确定是文字描述以及二维码是展现在图片上面的,刚开始我是网络

1. drawImage   文字,函数

2. drawImage    二维码测试

3. drawImage   背景大图

然而,结果让我大吃一惊,只有背景图加载渲染出来了。而后,经过无所不能的网络才知道:drawImage 的顺序应该是:图片最底下的须要最早加载渲染。

2.2 图片显示不完整

在2.1 问题出现的同时还遇到了这个问题,图片渲染不完整,这。。nima。。。需求才刚开始作,怎么这样为难一个小女子。。。

不过有问题嘛,就解决咯。

图片渲染不完整,缘由就是:在图片尚未加载完成的时候,canvas 就开始进行渲染。

 所以解决办法就是:等图片加载完成后再进行drawImage 操做就能够啦,上~~~~代码:

 

 

3.canvas 保存为图片的跨域问题

遇到这个问题,我真的是花了一堆一堆的时间来看文章,看博客,,。

这会万能的网友给个人解决办法并无任何效果:

他们说:1.把图片取下来放在本身服务器上(我用的公司的图片服务器。可是和个人放代码服务器不是同一个地址啊)

2. 用canvas2Image 啊,然而,,这不也是跨域么,,并无啥,,用。

3.还有啥来着,,忘了,反正那天搞得我精神崩溃,,,也没解决到问题,,后来实在忍不住,问了公司的大神:大神说:你用base64 的呢。。

一语惊喜梦中人,对啊,这种方法多棒,这样就不会跨域了啊。当时为了赶进度,直接在线吧图片转成basa64  ,而后存成一个js 文件。

当时是这样的:红框里表示的是文件的格式。。、

 

至此,个人html 已经转为canvas  而且从canvas 转为img 存在页面上了,,

 

后来我在看这一段,以为彷佛不太好,这个文件显得很大,因此我想在用这个文件的时候在把它转成base64 的格式,,

1.利用canvas todataUrl 将图片转为base64

可是这种方法不可避免的会出现跨域的问题,pass

2.base64.js  

这个文件中中文转码会出问题,并且我试过了,基本的字符串转码都是ok 的,可是对于文件转码就会出问题

3.浏览器原生的而且都支持的一个东西: window.atob     and   window.btoa

window.atob  是将base64 格式转换为字符串或者二进制编码格式

window.btoa  是将字符串或者二进制编码 格式转换为base64  格式  因此上面的base64.js 真的,,别浪费时间精力去看了,,

那文件编码解码呢?

原生的也有方法:FileRender()  这个构造函数,

var reader = new FileReader();

reader.onload = function(e) {

// e.target.result

};

reader.readAsDataURL(file);

这种方法没有测试过o(╥﹏╥)o。。

因此,目前为止,须要把文件转为base64. 格式的,我并无找到合适的方法或者js 插件来操做,若是各位有什么好的办法,麻烦告诉我(* ̄︶ ̄)。

 

 

4. 图片模糊而且窗口中只显示了一部分

才定义canvas 的时候,我是给canvas 定义了一个宽高的,宽高是背景图的大小,所以在drawImage 的时候是按照canvas 实际尺寸进行渲染。

可是转为图片的时候是按照窗口的尺寸来进行的,所以图片会模糊,若是给图片设置canvas 宽高的话,图片在窗口中又显示不完整。

所以,就须要计算设备的retio,

基本思路:计算出ratio  ---> 而后canvas 转 img (按照canvas 实际尺寸进行渲染) ---> 图片按照窗口大小进行缩放

这个方法直接返回的是设备的ratio..

而后咱们在进行canvas 渲染的时候,

在后面进行图片渲染的时候,图片的宽度直接除以 ratio ,这样图片就能完整的显示在窗口中。

 

 

 

5. ios10.2 canvas 转图片 一片黑

至此,页面是呈现出来了,而且在个人安卓(华为)上测试是ok

可是需求的同窗(ios)告诉我:她的手机上最后一页是黑色的和,顶部有个白色框,,,我一懵,天,不会ios 不支持吧。

因而,用了旁边座位同窗的手机。恩,也不行。。

啊啊啊啊啊,要崩溃。

在网上看了一下,有一种解决办法就是:使用双缓冲(出现黑屏的可能就是在drawImage 的时候计算量很大,而后渲染卡顿不成功)

大概思路就是:在新建一个cachecanvas 刚开始实际上是把图片渲染在这个缓存的canvas 中的,而后在将cachecanvas 中的内容渲染到须要在页面展现的canvas 中。

我在中间使用了一个延时,时间虽然很短,可是这样也能确保cachacanvas 确实渲染完成在进行正式的canvas 渲染。

这样,我周围座位上的ios 上最后一页都能显示出来了,,可是那个ios10.2 的依旧不行,,啊,网上查了一下,这个版本的问题一直存在,因此,(꒦_꒦) ,

 

 就这样,这个需求在我不断采坑的过程当中,好像也快完结了,这里不多直接贴代码进来,由于贴进来彷佛看的不太好,因此我基本上是截图的。

 

最后,几个小tips :

1.直接将网页图片存成base64 格式的,若是图片不多,能够,若是图片不少,仍是建议不要这么操做了,比较一个base64的数据格式就已经很大了。。。

2.图片先压缩,而后在进行base64格式编码吧

3.对于drawImage 的位置,是相对于canvas  实际尺寸的。因此若是使用百分比,建议先获得窗口的宽高,而后在进行赋值。

4. 在使用canvas   fillText 的时候,有一个限制最大宽度,就是fillText 的最后一个参数(直接写数值便可,不用带单位,默认彷佛是px)。

5.对于通常的H5,仍是对图片进行预加载一下吧,。。(网上不少图片预加载的方法,自行查找哦)。

相关文章
相关标签/搜索