最近需要生成分享海报,方便用户将图片保存到本地,分享到朋友圈。本来以为很简单的需求,没想到微信这么坑爹。一开始的思路是这样的:后台根据小程序传过来的参数获取对应的小程序代码,然后和背景图片合成后以base64格式发送给小程序,这样就不需要保存图像。但是尝试过后,有两个坑1:小程序对base64图片支持不友好,模拟器上可以显示图片,真机无法显示的坑2:小程序canvas绘图必须使用网络图片或者本地图片,但是如果直接在图片链接中传入wx.drawImage,真机会显示失败。记录于此,如有错误,请大神轻喷。首先是解决base64图片的问题。由于小程序支持不好,我们可以将它们保存在服务器上。下面是Laravel合成图片的简单代码:publicfunctiongetPoster(Request$request){$token=$request->input('token');$uid=MembersToken::getUidByToken($token);if(file_exists(public_path().'/poster/'.$uid.'.png')){returnresponse()->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);如果(isset($data['errcode'])||empty($data)){thrownewApiException(200,$data['errmsg'],null,[],600001);}$access_token=$data['access_token'];$expires_in=$data['expires_in'];缓存::put('access_token',$access_token,120);}//获取小程序代码$code_url='https://api.weixin.qq.com/wxa/getwxacodeunlimit?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,'右下角',0,0);$res=$img->save(public_path().'/poster/'.$uid.'.png');returnresponse()->json(['status'=>'success','data'=>'/poster/'.$uid.'.png']);}小程序获取到图片路径后,就可以使用画布绘制的方式展示图片,也可以直接使用图片标签的形式。为了防止以后可能对图片进行其他处理,我使用了canvas的方式。这时候如果直接使用后台传过来的图片路径,就会遇到第二个坑:真机上的图片无法显示。所以我们需要先使用wx.downloadFile来下载图片。嗯,代码大致是这样的:/***********************************************//**调用接口获取图片路径。..代码太糟糕了,不能省略。..**//***************************************************/wx.downloadFile({url:app.globalData.domain+res.data.data,success:function(res){varpath=res.tempFilePathvarwidth=_this.data.windowW;varheight=_this.data.windowH-50;constctx=wx.createCanvasContext('poster');ctx.drawImage(path,0,0,width,height);ctx.draw(true);wx.hideLoading();},失败:函数(res){/***/}})至此,图片应该可以在真机上正常显示了。接下来就是将图片下载到本地。解决完上面两个坑,就不会有什么大问题了。只需粘贴代码:saveImg:function(){var_this=this;varwindowW=_this.data.windowW;varwindowH=_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){/***/},失败(res){/***/},完成(res){/***/}})}});
