微信小程序图片保存到本地一次问题解决

6,548 阅读2分钟

背景

最近接到一个小程序保存二维码到本地的需求,以保证用户分享进行推广。看看似简单的一个小需求,其实还是挺麻烦的,为大家分享下(这里项目使用了Taro小程序是一样的)。

步骤

查看文档发现是现成的,很简单。

代码如下

// 图片下载
async downloadImage() {
  try {
    /**
    * @param {String} src  网络图片地址
    */
    const { path } = Taro.getImageInfo({ src })

    // 保存到相册
    const saveRet = await Taro.saveImageToPhotosAlbum({ filePath: path })

    if(saveRet.errMsg == 'saveImageToPhotosAlbum:ok') {
      Taro.showToast({
        title: '图片保存成功'
      })
    }
    
  } catch (error) {
    console.log(error)
  }
}

感觉好像是完事了,但其实还早,这才刚刚开始,刺激的在后面。

授权

调用相册是需要用户授权的,用户授权了还好,要是没有授权(用户选择了拒绝),就不能再进行图片下载,且没有什么提示,用户体验极差,怎么办呢。

最好的办法还是对用户进行引导。如果用户选择了拒绝,当用户再次打开此页面的时候,那么我们将下载的按钮进行替换成授权相册。引导用户手动打开相册权限进行图片的下载。

贴上代码供各位看官参考

async openSetting() {
  // 打开设置(手动授权)
  const ret = await Taro.openSetting()
  if(ret.authSetting['scope.writePhotosAlbum']) {
    this.setState({
      writePhotosAlbum: true // 权限开启状态
    })
  }
}

兼容性

本以为这样就结束了,奈何QA同学又过来找,在个别安卓手机上下载不了,表现为点击保存没有任何反应(文件类型识别失败)。

发现其实是getImageInfo这个方法获取不到图片信息报错导致的,惊慌失措中寻找是否有替代方案。 downloadFile是用来保存文件到本地的缓存中,存储临时地址。想到图片其实也是属于文件,尝试是否可以借助这个方法实现。

  // 获取临时文件路径
  const filePath = `${wx.env.USER_DATA_PATH}/${Date.now()}.jpg`
  // 通过获取本地临时文件路径进行图片的保存,此文件路径是我们自己指定了文件类型,所以不会出现文件类型识别失败的情况。
  const { path } = await Taro.downloadFile({
    url,
    filePath // 强行指定文件类型(.jpg)
  })
  // 图片保存
  const saveRet = await Taro.saveImageToPhotosAlbum({
    filePath: path
  })

  if(saveRet.errMsg == 'saveImageToPhotosAlbum:ok') {
    Taro.showToast({
      title: '图片保存成功'
    })

    // 保存成功之后移除缓存释放机身空间
    let fileMgr = Taro.getFileSystemManager()

    fileMgr.unlink({ filePath })
  }

这样实现之后是可以的,正好避过了getImageInfo获取图片类型(.png|.jpg)不成功的情况,如果各位小伙伴也遇到类似的场景,可以尝试将保存的代码修改成上面这种,能避免一些不必要的问题,如果有更好的办法,也请告知,欢迎一起学习讨论。祝工作顺利!

参考

关注我们

公众号@前端论道