H5中html页⾯存为图⽚并长按保存
最近接到的⼀个新需求:页⾯⼀个静态H5,中间有⼀页是输⼊信息,然后跳转到最后⼀页,⾃动将页⾯⽣成图⽚,⽤户可以长按图⽚保存到⼿机上。
展⽰⼀下最后⼀页的样⼦:
异地搬迁刚拿到这个需求,在⽹上看了很多⽂章,最普遍的是使⽤ html2canvas + canvas2image 来实现。于是,跟着前⼈的脚步,踏上了⼀个不断采坑采坑采坑的旅程。
下⾯直接描述我在做这个需求过程中遇到的问题以及解决办法吧:
如何做好防水漏水1.html2canvas 图⽚跨域:
这个问题⽹上很多解决办法:
这个是最常⽤的,刚开始我只是加了红⾊框⾥⾯的这⼀句,但是并没有任何作⽤,依旧报错。后来看到有⼈说,加上前⾯那⼀句,所以果断在加进去。
这两句其实表达的是同⼀个意思:允许图⽚跨域。
当然,也有⽹友说,直接给⼀个空值就可以,我当时试了⼀下,并不ok~~~~.
2.多次使⽤canvas drawImage ⽅法图⽚展⽰问题
2.1 图⽚加载顺序问题
在我这个需求⾥⾯,肯定是⽂字描述以及⼆维码是展⽰在图⽚上⾯的,刚开始我是
1. drawImage ⽂字,
2. drawImage ⼆维码
3. drawImage 背景⼤图
然⽽,结果让我⼤吃⼀惊,只有背景图加载渲染出来了。然后,通过⽆所不能的⽹络才知道:drawImage 的顺序应该是:图⽚最底下的需要最先加载渲染。
2.2 图⽚显⽰不完整
在2.1 问题出现的同时还遇到了这个问题,图⽚渲染不完整,这。。nima。。。需求才刚开始做,怎么这样为难⼀个⼩⼥⼦。。。
不过有问题嘛,就解决咯。
图⽚渲染不完整,原因就是:在图⽚还没有加载完成的时候,canvas 就开始进⾏渲染。
重阳节图片2022新图片因此解决办法就是:等图⽚加载完成后再进⾏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();
// sult
};
这种⽅法没有测试过o(╥﹏╥)o。。
所以,⽬前为⽌,需要把⽂件转为base64. 格式的,我并没有到合适的⽅法或者js 插件来操作,如果各位有什么好的办法,⿇烦告诉我(* ̄︶ ̄)。
4.图⽚模糊并且窗⼝中只显⽰了⼀部分
dnf手机令牌才定义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,还是对图⽚进⾏预加载⼀下吧,。。(⽹上很多图⽚预加载的⽅法,⾃⾏查哦)。
发布评论