微信小程序之canvas畫圖

開題

前幾天接到個需求,長按圖片保存到相冊,該圖片上有用戶頭像和暱稱以及對應的二維碼;那這就不能直接看成圖片來操做了,要先把總體圖片畫出來;我當時用的是canvas。效果圖以下:html

canvas drawImage

用canvas畫圖主要使用dramImage API,不太清楚的同窗能夠區MDN看看:developer.mozilla.org/zh-CN/docs/…canvas

主要是用到圖片URL,相對於左上角的x,y座標以及image在canvas上繪製的寬高。小程序

開始畫圖

那咱們開始行動了,先在html上寫個canvas標籤:微信小程序

<canvas canvas-id="shareCanvas" class="canvas" bindlongpress="saveImg" catchtouchmove="true" style="height: {{canvasHeight + 'rpx'}};width: {{canvasWidth + 'rpx'}};">
</canvas>
複製代碼

在微信小程序上畫圖先要把圖片路徑保存到本地,這裏咱們可使用wx.getImageInfo或者wx.downloadFile將圖片轉爲本地。考慮到咱們要操做多個圖片,這裏對這些API進行封裝:bash

getImageInfo(src) {
    return new Promise((resolve, reject) => {
        wx.getImageInfo({
            src,
            success: (res) => resolve(res),
            fail: (res) => reject(res)
        })
    });
}
複製代碼

若是你要使用downloadFile也能夠,封裝方法和上面同樣。 封裝好了那麼咱們能夠開始畫圖了,這裏須要三張圖片,對應的代碼以下:微信

Promise
    .all([
        this.getImageInfo('https://cyt-resource.oss-cn-shanghai.aliyuncs.com/wximg/qrcode_bg.jpg'),
        this.getImageInfo(this.data.userInfo.avatarUrl),
        this.getImageInfo(this.data.qrCodeUrl)
    ])
    .then((res) => {
        const ctx = wx.createCanvasContext('shareCanvas');
        ctx.drawImage(res[0].path, 0, 0, 圖片寬度, 圖片高度);

        ctx.fillStyle = 'rgb(168, 88, 126)'; // 字體顏色
        ctx.setFontSize(12); // 字體大小
        ctx.fillText(this.data.userInfo.nickname, 相對於左上角的x座標, 相對於左上角的y座標);

        ctx.drawImage(res[1].path, x座標, y座標, 寬, 高);
        ctx.drawImage(res[2].path, x, y, width, height);

        ctx.draw();

        this.setData({
            isDrawnImg: true
        });
    })
    .catch((e) => {
    });
複製代碼

在這裏要說個須要注意的坑,將圖片保存到本地須要在小程序後臺的downloadFile域名配置裏配置好對應的域名,一個都不能落, 好比微信頭像須要在downloadFile合法域名配置里加入https://wx.qlogo.cn; 另外須要提醒你們,在微信開發者工具裏調試的話儘可能不要開不校驗合法域名那個選項,即 微信開發

否則就會出如今調試模式下都是好的,可是真機不開調試就沒有效果了。並且很差排查錯誤。

優化

因爲canvas畫圖須要時間,那咱們能夠在等待時加個loading效果,在生成或者失敗時隱藏loading,失敗時還須要提示xss

wx.showLoading({
    title: '圖片生成中...'
});
wx.hideLoading();
wx.showToast({
    title: '圖片生成失敗'
});
複製代碼

保存圖片到相冊

這裏使用canvasToTempFilePath API,代碼以下:ide

saveImg () {
    wx.canvasToTempFilePath({
        canvasId: 'shareCanvas',
        success: (res) => {
            wx.saveImageToPhotosAlbum({
                filePath: res.tempFilePath,
                success: (res) => {
                    wx.showToast({
                        title: '保存成功'
                    });
                },
                fail: (res) => {
                    this.authorizeToWritePhotosAlbum();
                }
            })
        }
    })
},
複製代碼

這裏有個失敗時候的操做,主要是由於取消受權後就不能使用了,這裏要給個提示,讓用戶能夠再次選擇受權進行圖片保存,方法以下:工具

// 受權保存圖片至相冊
authorizeToWritePhotosAlbum () {
    wx.showModal({
        title: '提示',
        content: '須要您受權保存相冊',
        showCancel: false,
        success: (res) => {
          wx.openSetting({
            success: (res) => {
              if (settingdata.authSetting['scope.writePhotosAlbum']) {
                wx.showModal({
                  title: '提示',
                  content: '獲取權限成功,再次點擊圖片便可保存',
                  showCancel: false,
                });
              } else {
                wx.showModal({
                  title: '提示',
                  content: '獲取權限失敗,將沒法保存到相冊哦~',
                  showCancel: false,
                });
              }
            }
          })
        }
    });
},
複製代碼

至此,畫圖以及保存到相冊的問題都有解決了。那麼若是咱們須要適配呢,圖片須要自適應。在微信小程序咱們可使用rpx進行自適應:能夠看看文檔 developers.weixin.qq.com/miniprogram…

自適應

由於drawImage裏面的單位都是px,且不能更改,那咱們應該怎麼進行自適應。能夠根據設置的 設備屏幕/750*本身設置的自適應寬度(單位爲rpx),好比設置寬度爲600rpx,那麼在drawImage裏就是設備屏幕/750*600;要獲取屏幕高度直接調用wx.getSystemInfo就好了,取返回結果的screenWidth;文字大小,小圖片的x,y座標均可以經過這個方法進行自適應。

結題

我當時主要是域名配置忘了,坑了本身,而後就是受權問題(關閉後沒法保存,本身懵了,沒考慮到);但願你們都能注意下,寫的很差的地方但願你們提出來,一大早寫的比較匆忙,😄

相關文章
相關標籤/搜索