微信小程序使用 canvas 生成圖片分享到朋友圈

在小程序里,我們知道分享功能只有分享到微信好友或者群,無法直接分享到朋友圈,但是我們可以生成分享圖片,然后保存到相冊,在發(fā)布朋友圈從相冊選擇圖片,所以關鍵是如何生成需要的圖片,使用 canvas 畫布即可實現(xiàn)。

canvas 是微信小程序里的原生組件,相關屬性及注意事項可參考 小程序官方文檔 。一般生成分享圖片需要顯示文字和相應的圖片,在結合不同位置和不同大小的需求形成特定樣式的圖片。

首先需要在 wxml 里寫 canvas 的布局,例如:

<view class="canvas-box">
    <canvas  style="width: {{sysWidth}}px;height: {{canvasHeight}}px;"  canvas-id="shareCanvas" />
</view>

為什么我會在 canvas 控件外在加一個 view ,這個跟需求有關,后邊再說,如果只需要合成一張圖并不需要分享或者點擊預覽大圖的話可以只用一個 canvas 布局。我這里寬高都是計算出來的,因為生成的圖片有要求,canvas 標簽默認寬度300px、高度225px。canvas-id 是對應的每個畫布的 id ,同一頁面中的 canvas-id 不可重復,如果使用一個已經出現(xiàn)過的 canvas-id,該 canvas 標簽對應的畫布將被隱藏并不再正常工作。

我當時的需求是在商品詳情頁點擊分享按鈕自動生成商品對應的分享圖片,圖片需要包含商品標題、價格、商品展示圖片、商品詳情頁面的二維碼(掃碼可以直接進入當前商品詳情),使用畫布首先需要初始化畫布,

const canvasCtx = wx.createCanvasContext('shareCanvas'); //shareCanvas 是畫布的 id

然后繪制背景,如果想繪制一個寬高為屏幕寬度和屏幕高度的白色背景畫布,可以這樣寫:

  canvasCtx.setFillStyle('white');
  canvasCtx.fillRect(0, 0, this.data.sysWidth, this.data.sysHeight);

開始繪制商品標題,

 canvasCtx.setFontSize(18);//字體大小
 canvasCtx.setFillStyle('#f9555c');//字體顏色
 canvasCtx.setTextAlign('left');//字體對齊方式
 canvasCtx.fillText('這是商品標題', 20, 30);//20是 x 軸的坐標,30 是 y 軸的坐標,以此確定字的位置

說一下字體對齊方式,left 表示商品標題的最左端坐標為 x 軸的坐標,也就是上邊的20,如果對齊方式是 right 表示商品標題的最右端坐標為 20,不管標題多長結尾處都在20坐標點,center 表示標題的居中位置在20,即 x 軸上商品標題是以20作為對稱點的。這點需要知道,否則想當然的認為是相對屏幕居左、居右、居中對齊就不對了。

接下來畫圖,使用 CanvasContext.drawImage 方法,如下

 canvasCtx.drawImage(imgUrl, xPoint ,y, 120, 120); //圖片路徑,x軸坐標,y軸坐標,圖片寬,圖片高

跟文字相似,只是方法不同,最后需要加上

 canvasCtx.draw() //將之前在繪圖上下文中的描述(路徑、變形、樣式)畫到 canvas 中。

這樣就完成了在畫布上成功生成圖片的功能。

但是用畫布生成圖片還不行,由于在 canvas 上畫圖后圖片只是顯示在畫布上,不是使用 image 展示,也就不能直接保存圖片到相冊,同時由于 canvas 是原生組件,顯示在布局中會覆蓋其他控件,所以可以隱藏 canvas ,但是 canvas 仍會占據空間位置,所以上邊我在 canvas 外邊加了一個 view 父布局,父布局屬性如下,top 是為了讓 canvas 距離頂端足夠大,以隱藏 canvas ,如果使用 hidden 隱藏會仍占據位置,有空白區(qū)域。

.canvas-box {
    position: fixed;
    top: 99999px;
    left: 0;
}

最后需要將畫布上的圖片轉換成圖片,小程序官方提供了一個這樣的方法:wx.canvasToTempFilePath ,可以直接得到一個圖片路徑,將此圖片路徑賦值給 image 組件再顯示最終的圖片。舉個栗子?

    setTimeout(function() {
            wx.canvasToTempFilePath({
                    canvasId: 'shareCanvas',//定義的 canvas 的 id
                    success: function(res) {
                        var tempFilePath = res.tempFilePath;
                        console.log("合成圖片", tempFilePath)
                        self.setData({
                            shareImage: tempFilePath,
                        })
                    },
                    fail: function(res) {
                        wx.hideLoading();
                        console.log('生成失敗', res)
                    }
                })
          }, 50);

wxml 布局里需要一個 image 組件展示生成的圖片

  <image style="height: {{canvasHeight}}px;" mode="widthFix" class='share_image' src='{{shareImage}}' />

上邊轉換的地方加了一個 setTimeout 定時器,在定時到期以后執(zhí)行注冊的回調函數,防止畫布在 draw() 的時候沒有完成就執(zhí)行轉換圖片的方法會導致生成失敗的問題,所以加了一個延遲。

最后如果需要直接幫用戶保存此圖片,可以使用 wx.saveImageToPhotosAlbum 方法,注意調用前需要用戶授權。

生成的圖片如下(僅供參考):


wxe1d4583743a72332.o6zAJs751ABnLFg0uEtANRV-UTk8.FYKl8lLLpYdj96a5924ea0f459cdba653f3e39993791.png

以上就是生成圖片的方法,寫的比較啰嗦,其實沒有多麻煩,第一次接觸可能感覺比較復雜,但是總代碼量很少,有不懂的可以留言回復,感謝觀看。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容