call failed:, {"errMsg": "canvasToTempFilePath:fail invalid viewId"}苹果设备保存离屏 canvas 问题

发布时间 2023-12-13 15:12:11作者: 天葬

call failed:, {"errMsg": "canvasToTempFilePath:fail invalid viewId"}苹果设备保存离屏 canvas 问题

背景介绍

在使用 uniapp 开发微信小程序海报功能,使用了 微信小程序的 createOffscreenCanvas创建离屏 canvas 实例。苹果设备保存图片到相册报错

call failed:, {"errMsg": "canvasToTempFilePath:fail invalid viewId"}

相关网站

注意事项

  1. 微信小程序 canvas.createImage() 创建图片对象只能 onload 一次,下次还加载相同可能导致渲染不成功,所以可以在图片链接上加时间戳来解决次问题

    1. const cover = canvas.createImage()
      // 等待图片加载
      await new Promise(resolve => {
          cover.onload = resolve
          cover.src = this.cover + "?t=" + Date.now()
      })
      
  2. 离屏 canvas uni-app 下不显示,应该不支持

解决方案

canvas 是可以直接转 base64 数据,在 image 标签直接渲染的。所以这里保存 base64 文件到本地,再保存到相册。

// ……省略非关键代码
// 1、创建离屏 canvas 实例
const canvas = uni.createOffscreenCanvas({
    type: '2d',
    width: width,
    height: height
})
// 2、将画布转 base64 数据
this.imageData = canvas.toDataURL();
this.canvasData = canvas;

// ……省略非关键代码

// 保存文件代码
const fs = wx.getFileSystemManager()
const data = this.imageData.split(',')[1];
const path = `${wx.env.USER_DATA_PATH}/canvas.png`;
// 写入本地文件
fs.writeFile({
    filePath: path,
    data: data,
    encoding: 'base64',
    success(res) {
        uni.saveImageToPhotosAlbum({ // 保存相册
            filePath: path,
            success(ress) {
                uni.showToast({
                    icon: 'success',
                    mask: true,
                    title: '保存成功',
                });
            },
            fail: (err) => {
                console.log('err', err);
            }
        })
    },
    fail(res) {
        console.error(res)
    }
})