前言:由于小程序没有提供分享到朋友圈的功能,可以折中的将生成的海报分享到朋友圈。
效果图如下:

小程序博客生成海报功能

说明:生成海报需要用到微信提供的画布canvas来动态构造海报,构造海报需要资源:文章首图、文章标题、动态小程序码图片。获取图片时需将图片通过微信API下载缓存到小程序。
1.文章首图
获取图片可直接通过wx.getImageInfo

wx.getImageInfo({
  src: url,//将文章首图URL传入即可
  success (res) {
    console.log(res.path)
    this.setData({
      defaultImageUrl:res.path//获取到文章首图的缓存链接,后面canvas构图时需要用到
    })
  }
})

2.文章标题
直接调用文章原标题就可以
3.动态小程序码图片
作用:识别小程序码的时候可以直接进入文章内容页,可以配置小程序码进入页面的路径。
思路:获取动态小程序码我的做法是在wordpress网站里写了一个接口获取小程序码,生成海报功能的时候会首先判断云开发存储里面是否有对应文章的小程序码,如果没有就向接口请求小程序码,请求完毕后并将小程序码存到云开发存储中。(至于为什么要将小程序码存到云开发存储中,是因为网站在国外访问速度比较慢,所以折中的将小程序码存到云开发存储中,以加快生成海报功能的速度)
接口:第一次请求接口会判断是否已经存在文章对应的小程序码,如果没有再向微信请求的小程序码,并将其存在网站中,然后让接口返回动态小程序码的链接。
接口代码:

header('content-type:text/html;charset=utf-8');
$pathid=$_GET['id'];//文章ID,小程序请求接口的时候将ID传过来即可
$imgname="qrcode-".$pathid.".png"; //小程序码名称
if(is_null($pathid)){
  exit();
  //如果不存在文章Id结束请求
}
if(file_exists($imgname)){
  //已经存在文章对应的小程序码
  $imgurl="URL".$imgname;//将URL换成接口php文件的位置
  $data = array('imgurl' => $imgurl);
  //直接返回小程序码链接,并结束请求
  echo json_encode($data);
  exit();
}
//以下代码是向微信请求文章对应的小程序码
//配置APPID、APPSECRET
$APPID = "*****"; //换成你小程序的APPID
$APPSECRET =  "******";//换成你小程序的APPSECRET
//获取access_token
$access_token = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$APPID&secret=$APPSECRET";

//缓存access_token
 session_start();
 $_SESSION['access_token'] = "";
 $_SESSION['expires_in'] = 0;

$ACCESS_TOKEN = "";
 if(!isset($_SESSION['access_token']) || (isset($_SESSION['expires_in']) && time() > $_SESSION['expires_in']))
 {

<pre><code> $json = httpRequest( $access_token );
 $json = json_decode($json,true);
 // var_dump($json);
 $_SESSION['access_token'] = $json['access_token'];
 $_SESSION['expires_in'] = time()+7200;
 $ACCESS_TOKEN = $json["access_token"];

}
 else{

$ACCESS_TOKEN =  $_SESSION["access_token"];


}

//构建请求二维码参数
//path是扫描二维码跳转的小程序路径,可以带参数?id=xxx
//width是二维码宽度
$path="pages/single/single?id=".$pathid;//换成你所需要跳转的路径
$qcode ="https://api.weixin.qq.com/wxa/getwxacode?access_token=$ACCESS_TOKEN";
$param = json_encode(array("path"=>$path,"width"=> 150));

//POST参数
$result = httpRequest( $qcode, $param,"POST");
//生成二维码
file_put_contents($imgname, $result);
$base64_image ="data:image/jpeg;base64,".base64_encode( $result );
$imgurl="URL".$imgname;//将URL换成接口php文件的位置
$data = array('imgurl' => $imgurl);
echo json_encode($data);
//把请求发送到微信服务器换取二维码
  function httpRequest($url, $data='', $method='GET'){
    $curl = curl_init();<br />
    curl_setopt($curl, CURLOPT_URL, $url);<br />
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);<br />
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);<br />
    curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);<br />
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);<br />
    curl_setopt($curl, CURLOPT_AUTOREFERER, 1);<br />
    if($method=='POST')
    {
        curl_setopt($curl, CURLOPT_POST, 1);
        if ($data != '')
        {
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);<br />
        }
    }

curl_setopt($curl, CURLOPT_TIMEOUT, 30);  
curl_setopt($curl, CURLOPT_HEADER, 0);  
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);  
$result = curl_exec($curl);  
curl_close($curl);  
return $result;


}

小程序代码:
只贴出获取接口小程序码代码。获取、上传云开发存储的小程序码代码不贴出(如果你的网站访问速度快就不必用这段代码)

//获取接口小程序码

var that=this
wx.request({
 url: 'URL?id=' + articleid,//URL换成你接口的地址,articleid换成你文章对应的ID
 header: {
   'content-type': 'application/json' // 默认值
 },
 success(res) {
 //下载服务器上的小程序码
wx.getImageInfo({
  src: res.data.imgurl,//小程序码URL
  success (res) {
    console.log(res.path)
    var qrcodeimgUrl = res.path
    that.createPosterWithCanvas(defaultImageUrl, qrcodeimgUrl,title)//canvas画布构建函数,需要传入对应的参数(文章首图,小程序码,文章标题)
  }
 })
 }
 })

canvas画布构建函数代码

  /**
 * 利用画布生成海报
 */

  createPosterWithCanvas: function (postImageLocal, qrcodeLoal, title) {
    var that = this;
    var context = wx.createCanvasContext('mycanvas');
    context.setFillStyle('#ffffff');
    context.fillRect(0, 0, 600, 800);
    context.drawImage(postImageLocal, 0, 0, 600, 300); //绘制首图
    context.drawImage(qrcodeLoal, 210, 480, 180, 180); //绘制二维码
    context.setFillStyle("#000000");
    context.setFontSize(20);
    context.setTextAlign('center');
    context.fillText("阅读文章,请长按识别二维码", 300, 725);
    context.setFillStyle("#000000");
    context.beginPath() //分割线
    context.moveTo(30, 450)
    context.lineTo(570, 450)
    context.stroke();
    context.setTextAlign('left');
    context.setFontSize(35);

<pre><code>if (title.lengh &lt;= 12) {
  context.fillText(title, 40, 360);
} else {
  context.fillText(title.substring(0, 12), 40, 360);
  context.fillText(title.substring(12, 26), 40, 410);
}
context.draw();

setTimeout(function () {
  wx.canvasToTempFilePath({
    canvasId: 'mycanvas',
    success: function (res) {
      var tempFilePath = res.tempFilePath;
      wx.hideLoading();
      console.log("海报图片路径:" + res.tempFilePath);
      that.setData({
        showPosterPopup: true,
        showPosterImage: res.tempFilePath
      })
    },
    fail: function (res) {
      console.log(res);
    }
  });
}, 900);
},

/**
   * 取消保存海报图片
   */

  cacenlPosterImage: function () {
    this.setData({
      showPosterPopup: false
    })
  },
  /**
   * 保存海报图片
   */

  savePosterImage: function () {
    let that = this
    wx.saveImageToPhotosAlbum({
      filePath: that.data.showPosterImage,
      success(result) {
        console.log(result)
        wx.showModal({
          title: '提示',
          content: '二维码海报已存入手机相册,赶快分享到朋友圈吧',
          showCancel: false,
          success: function (res) {
            that.setData({
              showPosterPopup: false
            })
          }
        })
      },
      fail: function (err) {
        console.log(err);
        if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
          console.log("再次发起授权");
          wx.showModal({
            title: '用户未授权',
            content: '如需保存海报图片到相册,需获取授权.是否在授权管理中选中“保存到相册”?',
            showCancel: true,
            success: function (res) {
              if (res.confirm) {
                console.log('用户点击确定')
                wx.openSetting({
                  success: function success(res) {
                    console.log('打开设置', res.authSetting);
                    wx.openSetting({
                      success(settingdata) {
                        console.log(settingdata)
                        if (settingdata.authSetting['scope.writePhotosAlbum']) {
                          console.log('获取保存到相册权限成功');
                        } else {
                          console.log('获取保存到相册权限失败');
                        }
                      }
                    })
             }
            });
          }
        }
      })
    }
  }
});
},
  posterImageClick: function (e) {
    wx.previewImage({
      urls: [this.data.showPosterImage],
    });
  }

至于UI层面的代码就不贴出,由于代码过多,如果有兴趣的可以留言向我要这部分的源码。