最近在學小程序,在把當前畫布指定區域的內容導出並生成圖片保存到本地這個知識點上踩坑了。
這里用到的方法是: wx.canvasToTempFilePath(),該方法作用是把當前畫布指定區域的內容導出生成指定大小的圖片,並返回文件路徑。(詳情 看文檔)
這里先來分析一下這句話:導出當前畫布指定區域的內容並生成圖片 。這里以畫一個矩形並將該矩形保存到本地相冊為例。
首先我們要做的是先在畫布上畫一個矩形,其次是利用 wx.canvasToTempFilePath()方法導出畫布指定區域的內容,這里當然就是要保存這個矩形了,根據該方法返回的文件路徑,然后可以使用wx.saveImageToPhotosAlbum()方法將圖片保存到本地相冊了。
思路清晰了,現在可以着手實現了。
index.wxml中畫布代碼如下:
<button type="primary" bindtap="save">保存當前繪圖</button> <canvas canvas-id="myCanvas" style="border: 1px solid" />
畫矩形代碼如下(該代碼放在save方法中):
const ctx = wx.createCanvasContext('myCanvas') ctx.setFillStyle('red') ctx.fillRect(20, 20, 150, 100) ctx.draw()
此時點擊按鈕調用save方法,出現的效果如下:
現在要做的就是將這個紅色矩形導出來並存放到本地相冊。根據文檔的提示:需要在 draw
回調里調用wx.canvasToTempFilePath()方法才能保證圖片導出成功
那么以上代碼可以修改為這樣(此部分代碼存放在draw方法里):
wx.canvasToTempFilePath({ x: 20, y: 20, width: 150, height: 100, destWidth: 150, destHeight: 100, canvasId: 'myCanvas', success: function (res) { console.log(res.tempFilePath) // 返回圖片路徑 } })
這樣就完了嗎?並沒有,上面只是導出了矩形並返回了圖片路徑而沒有將圖片存放到本地,要實現這一點,還需要調用wx.saveImageToPhotosAlbum()方法,根據返回的路徑來保存該圖片到本地。
那么以上代碼又可以更改為(此部分代碼存放在draw方法里):
wx.canvasToTempFilePath({ x: 20, y: 20, width: 150, height: 100, destWidth: 150, destHeight: 100, canvasId: 'myCanvas', success: function (res) { wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, }) } })
進行到這一步,效果基本上已經實現了,注意,是基本上,,,,這里還存在着一個小bug,那就是在第一次生成圖片並保存的時候是一張相同大小但是卻是透明的圖片,並非是期望的紅色矩形,而之后生成的就是紅色的矩形圖片了,只有第一次不是,這是為什么呢?仔細分析了下,可能原因是,第一次保存圖片的時候,矩形可能並沒有繪制完成,因而裁剪后保存的是一張相同大小但是透明的圖片,於是我將上述代碼稍微做了調整,給它加了一個定時器。
const ctx = wx.createCanvasContext('myCanvas') ctx.setFillStyle('red') ctx.fillRect(20, 20, 150, 100) ctx.draw(true, setTimeout(function () { wx.canvasToTempFilePath({ x: 20, y: 20, width: 150, height: 100, destWidth: 150, destHeight: 100, canvasId: 'myCanvas', success: function (res) { wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, }) } }) },100))
好了,現在bug已經解決了,每次都能實現預期的效果了。
補充:最近開發小程序,使用了保存圖片到本地,按照正常流程走發現是沒有問題的,也就是說不存在第一次保存為空的情況,不需要再使用定時器來解決了。保存圖片到本地需要授權問題:
wx.saveImageToPhotosAlbum({ filePath: downUrl, // 需要保存的圖片地址 success(res) { wx.showToast({ title: '圖片保存中...', icon: 'loading', duration: 1000 }); setTimeout(function () { wx.showToast({ title: '圖片保存成功', icon: 'success', duration: 2000 }) }, 1000) }, fail: function (res) { if (res.errMsg === "saveImageToPhotosAlbum:fail auth deny" || res.errMsg == "saveImageToPhotosAlbum:fail:auth denied" || res.errMsg == "saveImageToPhotosAlbum:fail authorize no response") { wx.showModal({ title: '提示', content: '需要授權才可保存圖片', showCancel: false, success(res) { if (res.confirm) { wx.openSetting({ success(settingdata) { if (settingdata.authSetting["scope.writePhotosAlbum"]) { wx.showToast({ title: '獲取權限成功,再次點擊可保存圖片', icon: 'none', duration: 2000 }) } else { wx.showToast({ title: '獲取權限失敗', icon: 'none', duration: 2000 }) } }, fail() { wx.showToast({ title: '獲取權限失敗', icon: 'none', duration: 2000 }) } }) } } }) } } })