微信小程序生成小程序碼避坑指南

       最近在開發“生成小程序碼”功能,由於小程序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>

有更好的方法,請留言,謝謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章