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

       最近在开发“生成小程序码”功能,由于小程序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>

有更好的方法,请留言,谢谢

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