微信小程序 海报生成踩坑记
最近有个需求是要生成分享海报,让用户可以将图片保存到本地然后分享到朋友圈。本来以为是一个很简单的需求,可是万万没想到,微信会这么坑。
刚开始的思路是这样的:
- 坑1:小程序对base64图片支持不友好,模拟器上图片可以显示,真机无法显示
- 坑2:小程序canvas绘图必须使用网络图片或者本地图片,但是如果直接在wx.drawImage传入图片链接,真机上面会显示失败
Google一番之后,算是把这俩坑填上了。在此记录一下,有错误的地方还请大神轻喷。
首先是解决base64图片的问题,既然小程序支持的不好,那我们就保存在服务器好了,下面是Laravel合成图片的简单代码:
public function getPoster(Request $request) { $token = $request->input('token'); $uid = MembersToken::getUidByToken($token); if (file_exists(public_path() . '/poster/' . $uid . '.png')) { return response()->json([ 'status' => 'success', 'data' => '/poster/' . $uid . '.png' ]); } $access_token = Cache::get('access_token'); if (!$access_token) { $appid = config('wechat.appid'); $secret = config('wechat.secret'); $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}"; $data = curl_request($url); $data = json_decode($data,true); if (isset($data['errcode']) || empty($data)) { throw new ApiException(200,$data['errmsg'],null,[],600001); } $access_token = $data['access_token']; $expires_in = $data['expires_in']; Cache::put('access_token',$access_token,120); } //获取小程序码 $code_url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' . $access_token; $post = [ "page" => "pages/maps/maps", "scene" => $uid, ]; $data = curl_request($code_url, $post); $data = base64_encode($data); $data = Image::make($data)->resize(200, 200); //将二维码插入背景图 $img = Image::make(public_path().'/img/book.png'); $img->insert($data, 'bottom-right', 0, 0); $res = $img->save(public_path() . '/poster/' . $uid . '.png'); return response()->json([ 'status' => 'success', 'data' => '/poster/' . $uid . '.png' ]); }
小程序获取到图片路径之后,可以使用canvas绘图的方式显示图片也可以直接使用image标签的形式。为了防止以后可能对图片进行别的处理,我使用了canvas的方式。
此时如果直接使用后台传过来的图片路径的话,就会遇到第二个坑:在真机上面图片是显示不出来的。因此我们需要先使用wx.downloadFile将图片下载下来。嗯,代码差不多就是下面这样:
/***********************************************/ /**调用接口获取图片路径。。。代码太烂省略了。。。**/ /**********************************************/ wx.downloadFile({ url: app.globalData.domain + res.data.data, success: function (res) { var path = res.tempFilePath var width = _this.data.windowW; var height = _this.data.windowH - 50; const ctx = wx.createCanvasContext('poster'); ctx.drawImage(path, 0, 0, width, height); ctx.draw(true); wx.hideLoading(); }, fail: function (res) { /***/ } })
此时,图片应该可以正常的在真机上面显示了。接下来就是下载图片到本地了,解决了上面两个坑之后这块就没什么大问题了,简单贴一下代码:
saveImg: function () { var _this = this; var windowW = _this.data.windowW; var windowH = _this.data.windowH - 50; wx.canvasToTempFilePath({ x: 0, y: 0, width: windowW, height: windowH, destWidth: windowW, destHeight: windowH, canvasId: 'poster', success: function (res) { wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success(res) { /***/ }, fail(res) { /***/ }, complete(res) { /***/ } }) } });
相关推荐
powderhose 2020-06-08
kgshuo 2020-09-25
Tomato 2020-09-10
taiyangyu 2020-09-10
CodeAndroid 2020-09-10
small 2020-07-29
sucheng 2020-07-26
zuoliangzhu 2020-07-20
CodeAndroid 2020-07-14
xiaoxubbs 2020-07-04
sucheng 2020-06-25
kgshuo 2020-06-14
意外金喜 2020-06-14
zuoliangzhu 2020-06-14
tianping 2020-06-14
hgzhang 2020-06-14
killgod 2020-06-14
戴翔的技术 2020-06-14