微信小程序保存图片到本地,base64?buffer?

4,287 阅读4分钟

小程序提供有wx.saveImageToPhotosAlbum可以保存图片到本地,可是参数filePath有如下说明:

图片文件路径,可以是临时文件路径或永久文件路径 (本地路径) ,不支持网络路径

可是如果是base64或者是buffer流呢?

最近有一个需求(下面会说到),正好遇到了这个问题,记录一下。

OK,言归正传:

1、需求 小程序为每个登录的用户生成一个二维码(或者小程序码),推广出去,其他用户通过扫描这张二维码进入小程序时候可以知道是通过谁的二维码进入的。

2、分析 知道需求后思路大概就有了:在小程序中生成带有用户唯一标识的小程序的二维码(或小程序码),然后保存到本地供用户使用。

3、动手 思路清晰后,就开始动手吧,先查文档

  • 获取小程序码 文档中给出了几种生成的方式,可以通过对比各自特点结合业务场景选择,我这里使用了wxacode.getUnlimited 调用方式有两种:1、https调用。 2、云调用 第一种方式需要后端同学配合,与微信交互获取access_token就是接口调用凭证。 第二种方式也就是本文使用的方式是通过微信小程序云开发的能力来调用的。 开通了云开发后项目根目录下应该有一个cloudFun文件夹,这是存放云函数的,右击这个文件夹,点击新建Node.js云函数 名字随意,我的是createQrCode
  cloudFun
+ |- createQrCode
+   |- config.json
+   |- index.js
+   |- package.json

现在文件结构应该是这样的。

// config.json

{
  "permissions": {
    "openapi": [
      "wxacode.getUnlimited"
    ]
  }
}
// index.js

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 云函数入口函数
exports.main = async (event, context) => {
  try {
    const result = await cloud.openapi.wxacode.getUnlimited({
      scene: 'userId=123',  // 这里用userId作为小程序码的唯一标识
    })
    return result;
  } catch (err) {
    throw err;
  }
}

package.json默认不用修改。

云函数这就创建好了,然后右击新建的createQrCode文件夹,点击上传并部署:云端安装依赖


上面已经创建好了云函数,现在要使用了。

wx.cloud.init();
  wx.cloud.callFunction({
    name: 'createQrCode',  // 云函数的名字
    complete: res => {
      console.log(res)
    }
  })

这里打印结果如下图:

res.result.buffer就是我们获取的小程序码的图片,只不过是buffer流的形式 然后我们要把图片保存到本地,但是buffer的怎么保存呢?上面微信保存图片API的参数只支持文件路径。 直接看代码:

wx.cloud.init();
  wx.cloud.callFunction({
    name: 'createQrCode',  // 云函数的名字
    complete: res => {
      const buffer = res.result.buffer;
      var manager = wx.getFileSystemManager();
      manager.writeFile({
        filePath: wx.env.USER_DATA_PATH + '/qucode.png',
        data: buffer,
        success: res => {
          wx.saveImageToPhotosAlbum({
            filePath: wx.env.USER_DATA_PATH + '/qucode.png',
            success: function () {
              wx.showToast({
                title: '保存成功',
              })
            },
            fail: function (err) {
              console.log(err)
            }
          })
        }, fail: err => {
          console.log(err)
        }
     })
    }
  })

arrayBufferToBase64 其实就是通过wx.getFileSystemManager获取文件管理器,然后调用writeFile方法写入文件,这时候就有图片的路径了,然后再调用wx.saveImageToPhotosAlbum就可以了。 文档在这里FileSystemManager.writeFile

其中wx.env.USER_DATA_PATH是小程序中的一个环境变量,代表文件系统中的用户目录路径

可以看到文档中writeFile还支持base64格式的内容,我们还可以把buffer转成base64然后再调用这个方法,效果是一样的,只不过参数encoding要改成'base64'

let base64 = wx.arrayBufferToBase64(buffer);  // 这样就可以把buffer转成base64了

这样保存小程序码就可以保存到本地了,但是别忘了我们还带了个参数userId=123呢,这怎么取呢? 其实app.js里面的onLaunchonShow方法可以接收一个参数options,我们来打印看看。

App({
    onLaunch: function(options) {
        console.log(options, 'onLaunch')
    },
    
    onShow: function(options) {
        console.log(options, 'onShow')
    },
    
    ...
})

可以看到,两个地方打印的options是一样的,但是里面好像没有我们要找的参数,这是因为我用的是普通编译模式,可以切换成通过二维码编译,选择刚才保存在本地的小程序码图片:

选择通过二维码编译,选择刚才保存的图片,然后再看打印信息

可以看到我们刚才传的参数在options.query.scene里面,但是内容是被格式化成了escape格式的,所以我们通过decodeURIComponent就可以取到源参数了。

App({
    onLaunch: function(options) {
        console.log(decodeURIComponent(options.query.scene), 'onLaunch')
    },
    
    onShow: function(options) {
        console.log(options.query.scene, 'onShow')
    },
    
    ...
})

可以看到现在已经取到了正确的参数了。

觉得有帮助就点个赞吧。