1. 程式人生 > >微信小程式之生成圖片分享

微信小程式之生成圖片分享

通過社交軟體分享的方式來進行營銷小程式,是一個常用的運營途徑。小程式本身支援直接將一個小程式的連結卡片分享至微信好友或微信群,然後別人就可以通過點選該卡片進入該小程式頁面。但是小程式目前不支援直接分享到微信朋友圈,而對我們來說,微信朋友圈又是一個很重要的吸引別人關注的入口,所以,得想辦法把這個資源利用起來。

可能有的人已經知道,微信小程式支援通過掃描/長按識別二維碼或小程式碼圖片的方式進入一個小程式首頁或小程式中某個特定頁面(如何生成這類常規二維碼、小程式碼,可參考《微信小程式之生成自定義引數小程式二維碼》這篇文章),我們可以將二維碼或小程式碼分享到朋友圈去。

不過,這種二維碼看起來比較單調,不太感人!

為了提升吸引力,我們可以把這種用於分享出去的二維碼圖片做的儘量美觀、有情景感一些,比如像騰訊出品的小程式《長城你造不造》裡生成的這種分享圖片:

這種配有圖文的圖片,就比單單給一個硬邦邦的二維碼要吸引人得多啦!你是不是也想試試做這種分享圖呢?我們今天就來討論一下如何實現這樣的分享圖。

實現這種合併圖文的方案,選擇無外乎就是在前端做還是在後端做。如果在後端做的話,可選的技術方案還是挺多的,各種後端語言都有自己的繪圖工具庫,比如nodejs裡可以用node-canvas來做,或者也可以通過呼叫一些圖片編輯軟體(如ImageMagic)來實現。

而在前端做的話,由於微信小程式也提供了一系列基於canvas的繪圖相關API,所以繪製這樣的圖片還是比較簡單易上手的,且除錯起來也比較方便直觀。所以,決定先在小程式前端這邊來實現了。

新增畫布

首先,在小程式裡進行繪圖操作需要用到元件,那我們就先在我們的wxml程式碼中放入如下的:

<canvas canvas-id="shareCanvas" style="width:600px;height:900px"></canvas> 

這樣一來我們就有了一個600x900的繪圖區域。然後,我們要開始寫JS程式碼在這張畫布上進行繪圖操作。

步驟1:繪製背景圖

通過觀察《長城你造不造》合成的那張分享圖,我們可以分析得出它的組成主要有以下3個部分:一張大的背景圖,一段動態的文字(xxxx 喊你“一起來為修長城獻磚”),以及一個小程式碼圖片。

那麼我們就先找一張圖片來當做背景圖,將它畫到畫布上去,程式碼大致如下:

const wxGetImageInfo = promisify(wx.getImageInfo)

wxGetImageInfo({
   src: 'http://some-domain/bg.png'
}).then(res => {
const ctx = wx.createCanvasContext('shareCanvas')
   ctx.drawImage(res.path, 0, 0, 600, 900)
   ctx.draw()
})

在這段程式碼中,我們通過使用wx.getImageInfo這個API來下載一個網路圖片到本地(並可獲取該圖片的尺寸等其他資訊),然後呼叫ctx.drawImage方法將圖片繪製到畫布上,填滿畫布。

步驟2:繪製文字

接著,讓我們來在畫布上繼續繪製一段文字,一般這種宣傳用的分享圖,少不了文字描述,而且可能是根據場景內容不同而產生的動態資訊,比如可能是一篇文章的作者、文章的標題和內容。

我們嘗試下在畫布上新增一段居中顯示的文字:“作者:一斤程式碼”,還是基於前面的那段程式碼接著寫:

const wxGetImageInfo = promisify(wx.getImageInfo)

wxGetImageInfo({
   src: 'http://some-domain/bg.png'
}).then(res => {
const ctx = wx.createCanvasContext('shareCanvas')

// 底圖
   ctx.drawImage(res.path, 0, 0, 600, 900)

// 作者名稱
   ctx.setTextAlign('center') // 文字居中
   ctx.setFillStyle('#000000') // 文字顏色:黑色
   ctx.setFontSize(22) // 文字字號:22px
   ctx.fillText(“作者:一斤程式碼”, 600 / 2, 500)

   ctx.stroke()
   ctx.draw()
})

由於在canvas上繪製文字不會自動折行,如果要畫一段比較長的文字,可以考慮限制一行的字數,將長文字拆分成幾行來畫。

步驟3:繪製小程式碼

最後,我們在畫布最後新增一個小程式碼,可以是靜態的小程式碼,也可以是比如為每一篇文章動態生成的小程式碼(參考《微信小程式之生成自定義引數小程式二維碼》這篇文章),反正這個小程式碼也就是一張圖片,所以繪製方法跟繪製底圖差不多。最後的程式碼類似如此:

const wxGetImageInfo = promisify(wx.getImageInfo)

Promise.all([
   wxGetImageInfo({
       src: 'http://some-domain.com/background.png'
}),
   wxGetImageInfo({
       src: 'http://some-domain.com/api/generate/qrcode'
})
]).then(res => {
const ctx = wx.createCanvasContext('shareCanvas')

// 底圖
   ctx.drawImage(res[0].path, 0, 0, 600, 900)

// 作者名稱
   ctx.setTextAlign('center') // 文字居中
   ctx.setFillStyle('#000000') // 文字顏色:黑色
   ctx.setFontSize(22) // 文字字號:22px
   ctx.fillText(“作者:一斤程式碼”, 600 / 2, 500)

// 小程式碼
const qrImgSize = 180
   ctx.drawImage(res[1].path, (600 - qrImgSize) / 2, 530, qrImgSize, qrImgSize)

   ctx.stroke()
   ctx.draw()
})

這樣,差不多我們的分享圖就生成好了。

儲存到系統相簿

接著,我們要把它儲存進使用者的系統相簿中去,實現這個功能,我們主要靠wx.canvasToTempFilePath和wx.saveImageToPhotosAlbum這兩個API。

主要的流程就是先通過wx.canvasToTempFilePath將上繪製的影象生成臨時檔案的形式,然後再通過wx.saveImageToPhotosAlbum進行儲存到系統相簿的操作。

const wxCanvasToTempFilePath = promisify(wx.canvasToTempFilePath)
const wxSaveImageToPhotosAlbum = promisify(wx.saveImageToPhotosAlbum)

wxCanvasToTempFilePath({
   canvasId: 'shareCanvas'
}, this).then(res => {
return wxSaveImageToPhotosAlbum({
       filePath: res.tempFilePath
})
}).then(res => {
   wx.showToast({
       title: '已儲存到相簿'
})
}) 

以上就是在微信小程式裡合成一個朋友圈分享用的小程式推廣圖片的簡要流程了,程式碼僅供參考,實戰可自由發揮:)