这里先说明一下.个人小程序是实现不了的,所以我的这个博客,是没有办法使用这个功能的,不知道以后微信会不会开放这个功能给个人吧…
公司现在的项目,也需要使用推荐邀请的机制了,而小程序很蛋疼的一点就是,不能直接发送到朋友圈(APP是可以直接发送到朋友圈的),于是,推广海报这个功能就应运而生了…
在这里再贴一下我自己的小程序二维码,欢迎大家访问,评论.
基本上大型的小程序都有分享海报的功能,比如美团:
这个太阳码扫了就能直接进入对应的店铺,不用在美团上再慢慢搜索查询,不过因为我现在这个项目的二维码生成机制的问题,太阳码的限制只有十万个,所以我的不能用太阳码,只能用普通的链接二维码了.
这里先说一下二维码的生成规则:
因为我要做的是带参二维码,为了支持更多的参数,结尾肯定是带json字符串的,然后,链接一定要以斜杠结尾,才能带参:
扫描带参二维码的时候.小程序的onload(option)中的option.q的值为https://xxx.xxx.xxx/xxx/xxx/{"xxx":"xxx"},然后自己再来解析这个字符串,就可以得到想要的信息,比如分享这个二维码的用户ID等等
这里要注意的时候这个链接是必须在公网上能访问到的,并且已经把相应的验证文件放在了这个url里面, 不然微信是不会认同这个URL,你也设置不上去的.这些东西.具体的大家进小程序后台看说明就好了.就不在这里详细说了.
先来看一下我要生成的推广海报的大概效果图:
这个海报由一个不带二维码的模板图片.与一个动态生成的二维码组成,模板图片我放在了阿里里云的对象存储桶中.
第一个坑,就是小程序中的canvas,并不支持加载网络图片,而且是真机不支持,有时候在微信开发者工具里面,你用网络图片是没问题的.但是一换到真机调试就挂了,解决这个坑.那就只能是先下载图片到本地,然后再用canvas把本地图片画进画布了,关键代码如下:
1 | uni.getImageInfo({ |
上面的代码,主要是uni.getImageInfo这个方法.与success这个回调中的res的信息(我用的不是原生的小程序开发,而是用的uniapp这个框架,不过uni.getImageInfo与wx.getImageInfo基本上在小程序中的使用是一样的)这个res.path就是下载这个网络图片后存储在微信本地缓存中的图片路径,这时再来用canvas加载.
第二个坑,因为这个uni.getImageInfo的方法,下载图片非常之慢,所以我想一进入主页就直接下载,然后画在canvas上,这样直接点生成海报就可以直接生成图片,但是这个想法也破灭了,因为在canvas画布所在的父元素为隐藏的情况下,画布的draw方法,是不会把图片内容画进画布的.也就是说.一定要打开生成海报的界面,然后再来通过画布生成图片,开始偷偷生成的文件,全是黑屏,自己脑袋都快抓破了,才想起来可能是这个问题,而且,完全不知道为什么…
第三个坑,canvas在调用draw方法以后,图片并没有马上画出来,这时候你用uni.canvasToTempFilePath或者是wx.canvasToTempFilePath的时候,文件一样不会正常出现…为什么呢?canvas的draw有一个回调,在画布画完以后,可以触发,这个在微信官方,并没有例子在canvas.draw()的示例方法中,示例中都是直接.draw(),然后再进行下一步操作…只在wx.canvasToTempFilePath方法中,提了一句话:”wx.canvasToTempFilePath(Object object, Object this)
把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功”,一不小心就会忽略过去,直接看API的那些属性方法什么的,但是如果你不够仔细…这个坑也能坑到你头疼.那么正确的写法如下:
1 | this.context.draw(true,res =>{ |
上面的success回调中用res.tempFilePath就是画布画完以后保存到本地的临时图片路径,这个路径是可以在小程序的image标签的src属性中生效的.踩坑好像到这里就结束了,但是还二维码没弄.然后,坑就又来了…
第四个坑,二维码生成的是base64编码,如果是一般的网页上.无非就是var image = new Image(),然后image.src = base64编码就加载出来完事了,但是小程序有这么简单吗?????没有!!!!
base64 格式图片数据,无法被 getImageInfo 直接调用,要先用wx.base64ToArrayBuffer方法将base64 数据转换为 ArrayBuffer 数据,然后用wx.getFileSystemManager().writeFile方法将ArrayBuffer 写为本地临时图片文件,最后再调用 canvas的drawImage方法,将图片画进画布中,这里我觉得自己被恶心到了…而且一直报了个无端的错误,最后排查了很久,才发现是回调的先后顺序问题,最后才解决.这里也想吐糟一下uniapp,这几个方法,uniapp没一个支持的…写的都是wx.xxx而不是uni.xxx了,这个到了app里, 估计代码又得换一大堆.很难受…base64到画布然后再生成图片的代码如下:
1 | let base64data = this.$refs.qrcode.img; |
感觉到这里基本上就可以了.图片也正常生成了.下面是效果:
点击保存图片,然后图片就保存到了相册.本以为到这里就结束了.最后发现还是有问题…
第五个坑,上面的图片中的海报是我用canvas直接生成的,但是这个图片,偏小了,真正发送给别人.别人点开的时候一全屏,就会有点模糊,体验不够好,这个问题还好,虽然是坑,但是很好解决,canvas与真实的二维码,我都放在了界面的两边,样式中加上position:fixed直接left或者是right设置成750px,然后canvas画布不再用图中的卡片的大小,而用这个模板图本来的大小(我做的图,默认宽度就是750px)canvas在手机屏幕的两边看不到的地方.一直都存在着,而中间的这个卡片只是src为canvas生成的临时图片的路径,在界面上看起来小,但是点保存的时候保存的是宽高较大的canvas生成的大图,这样在微信中打开的时候.也很清晰明了.
一路走来一路坑.感觉终于出了个东西,可以交差了.在公司里用别的人手机直接扫分享的二维码,确怎么都不对,也没查询出相应的数据,这个问题,也让我一阵头大…
第六个坑,微信开发者工具在本地开发版的小程序中,确实可以不用较难合法域名等信息,但是,用真机调试的时候,即使你设置的当前这个二维码规则只在开发版中生效,但是小程序的开发者用微信扫描这些带参二维码的时候,一定是要校验合法域名的,不是https是不行的.本人用ngrok免费的随机域名几个月了,头一回遇到这个问题搞了好久的真机调试,将错误用uni.showModal把信息展示出来,才发现是这个问题…简单的说来,配置的链接规则虽然在开发版中生效,但是想多个开发者直接扫描二维码测试,还是得用https…最好还是自定义域名.这样方便一些.
这里顺便提一下第七个坑,在购买ngrok自定义域名的https外网映射的时候.一定要注意,自定义域名,国内不同的ngrok服务商,对域名的要求是不一样的,有的是要求在腾讯云备案,有的却相反要求在阿里云备案(小程序的域名要在阿里云备案,我也就呵呵了…还好我在腾讯云和阿里云都有域名),有的没有什么要求.这些最好在购买之前就要了解清楚.不然钱出了问题还没解决.
总得说来,这个生成海报,就这些坑了,希望大家如果能看到这篇博客的话,能在少走一些弯路的同时,也能多跳过一些坑…
最后,发个成品动态图吧: