最近在開發“生成小程序碼”功能,由於小程序canvas組件在真機中無法渲染base64格式的圖片,所以使用writeFile方法在客戶端創建圖片的思路實現。
但發現,如果圖片名字是一樣的話,儘管“小程序碼接口”每次返回的ArrayBuffer數據不一樣,安卓機還是會出現圖片不更新的情況。於是思路變成,創建一個目錄,每次在這個目錄下生成隨機名字的圖片,爲避免造成緩存過大,每次生成圖片前都清空目錄。
以下代碼中使用了開發者文檔中的一個二維碼,所以存在跨越問題,請勾選
js代碼
const dir = wx.env.USER_DATA_PATH + '/test';
Page({
data: {
codeSrc: ''
},
onLoad: function (options) {
this.createPhoto();
},
createPhoto() {
Promise.all([
this.getCodeBuffer(),//獲取小程序碼ArrayBuffer數據
this.clearFiles()//清除客戶端緩存的圖片,避免緩存過大,留意方法裏的註釋
])
.then(res => {
return this.writeFile(res[0].result.buffer);//在客戶端創建一個圖片
})
.then(res => {
//生成臨時圖片路徑
return new Promise((resolve,reject) => {
const ctx = wx.createCanvasContext('J-canvas');
ctx.drawImage(res, 0, 0, 200, 200);
ctx.draw(true, res => {
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: 200,
height: 200,
canvasId: 'J-canvas',
success: (res => {
resolve(res.tempFilePath)
}),
fail: (e => {
reject()
})
})
})
});
})
.then(res => {
this.setData({
codeSrc: res
});
})
.catch(e => {
console.log(e)
})
},
/*
此處模擬獲取小程序碼接口返回ArrayBuffer格式數據,真實情況詳見 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html
*/
getCodeBuffer() {
return new Promise((resolve, reject) => {
wx.request({
url: 'https://res.wx.qq.com/wxdoc/dist/assets/img/demo.2333a2a0.png',
responseType: 'arraybuffer',
success(res) {
resolve({
result: {
buffer: res.data
}
})
},
fail: (e => {
reject(e)
})
})
})
},
/*
本例子中writeFile方法,生成的是一個隨機名字的圖片,所以每次生成圖片之前都創建一個目錄,而且清除當前目錄所有文件,確保這個文件夾下只有一個圖片,這樣就不會緩存過大,安卓機也不會存在文件不更新的問題
*/
clearFiles() {
const fileSystemManager = wx.getFileSystemManager();
return new Promise((resolve, reject) => {
fileSystemManager.mkdir({
dirPath: dir,
complete: e => {
fileSystemManager.readdir({
dirPath: dir,
success: (res => {
for (let item of res.files) {
fileSystemManager.unlinkSync([dir, item].join('/'))
}
resolve();
}),
fail: (e => {
reject(e)
})
})
}
})
})
},
/*
在test文件夾下生成一個隨機名稱的圖片,並返回路徑
*/
writeFile(buffer) {
const filePath = dir + '/' + new Date().getTime() + '.jpg';
return new Promise((resolve, reject) => {
wx.getFileSystemManager()
.writeFile({
filePath,
data: buffer,
encoding: 'binary',
success() {
resolve(filePath)
},
fail() {
reject()
}
});
})
}
})
wxml代碼
<canvas canvas-id='J-canvas' style="width:300px;height:300px;"></canvas>
<image src="{{ codeSrc }}" style="width:300px;height:300px;" show-menu-by-longpress></image>
有更好的方法,請留言,謝謝