当前位置: 首页 > news >正文

uniApp小程序保存canvas图片

最近写了需求 用 canvas 保存 2 张图片叠在一起 并保存手机相册 先上代码

<wd-button type="primary" class="download-btn" @click="downloadImage">下载图片</wd-button>

<canvas
    canvas-id="mergeCanvas"
    style="position: absolute; left: -9999px; width: 300px; height: 400px"
    width="300"
    height="300"
  ></canvas>
//这里的canvas的dom元素 如果不想展示的话 可以用上面的style

// 下载图片
const downloadImage = async () => {
  uni.getSetting({
    success(res) {
      console.log(res.authSetting, 'res.authSetting')

      if (!res.authSetting['scope.writePhotosAlbum']) {
        uni.authorize({
          scope: 'scope.writePhotosAlbum',
          success() {
            saveImg()
          },
        })
      } else {
        saveImg()
      }
    },
  })
}

// 合并图片方法
const mergeImages = async () => {
  try {
    return new Promise((resolve, reject) => {
      const ctx = uni.createCanvasContext('mergeCanvas', proxy) // 使用 proxy
      // 获取底图信息
      uni.getImageInfo({
        src: 'https://xxx.com',
        success: (baseRes) => {
          const width = 300
          const height = 400
          // 绘制底图
          ctx.drawImage(baseRes.path, 0, 0, width, height)
          // 获取叠加图信息
          uni.getImageInfo({
            src: data.deviceInfo.image,
            success: (overlayRes) => {
              // 绘制叠加图
              ctx.drawImage(overlayRes.path, 55, 105, 187, 187)

              // 添加码牌编号
              ctx.setFontSize(16) // 设置字体大小
              ctx.setFillStyle('black') // 设置字体颜色
              ctx.fillText(`LSF${data.deviceInfo.merchantCodeId}`, width * 0.32, height * 0.74) // 在底部添加码牌编号

              // 执行绘制操作
              setTimeout(() => {
                ctx.draw(false, () => {
                  uni.canvasToTempFilePath({
                    canvasId: 'mergeCanvas',
                    success: (res) => {
                      resolve(res.tempFilePath)
                    },
                    fail: (err) => {
                      reject(err)
                    },
                  })
                })
              }, 100)
            },
            fail: (err) => {
              console.error('叠加图加载失败:', err)
              reject(err)
            },
          })
        },
        fail: (err) => {
          console.error('底图加载失败:', err)
          reject(err)
        },
      })
    })
  } catch (error) {
    console.log(error, 'error')
  }
}

const saveImg = async () => {
  try {
    uni.showLoading({ title: '图片保存中...' })

    const mergedImagePath = await mergeImages()

    // 保存图片到相册
    uni.saveImageToPhotosAlbum({
      filePath: mergedImagePath,
      success: () => {
        uni.showToast({ title: '保存成功', icon: 'success' })
      },
      fail: (err) => {
        console.log(err, 'err')

        if (err.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {
          uni.openSetting({
            success(settingdata) {
              if (settingdata.authSetting['scope.writePhotosAlbum']) {
                uni.showToast({
                  title: '您已授权成功,请重新保存',
                  icon: 'success',
                  duration: 2000,
                })
              } else {
                uni.showToast({
                  title: '尚未授权,无法保存海报',
                  icon: 'none',
                  duration: 2000,
                })
              }
            },
          })
        }
      },
      complete: () => {
        uni.hideLoading() // 确保在操作完成后隐藏加载提示
      },
    })
  } catch (error) {
    console.log(error)
    uni.showToast({ title: '图片生成失败', icon: 'none' })
    // uni.hideLoading() // 确保在捕获错误时也隐藏加载提示
  }
}

代码看起来没问题 但上线后就下载不了 体验版可以下载 找了很久 发现 需要去设置一下微信小程序的用户隐私保护指引

这里显示已更新就行 没有处理的 需要先处理一下 才能发起权限

相关文章:

  • 第一章 1.什么是 AI 量化炒股
  • 机器视觉3D深度图颜色含义解析
  • 【Linux】Linux 文件系统—— 探讨软链接(symbolic link)
  • 使用 deepseek实现 go语言,读取文本文件的功能,要求支持 ascii,utf-8 等多种格式自适应
  • JAVA JUC 并发编程学习笔记(一)
  • CVE-2023-32233NetFilter权限提升复现
  • Lua C API :使用 lua_tonumber 函数从 Lua 栈中提取数值
  • 2025vue4.x全栈学习关键技术分析线路图
  • SSE/Fetch API+Stream/WebSocket实时流式接收Node后端传来的处理过后的Coze API数据
  • uni-app开发安卓和ios app 真机调试
  • 探索无网用Deepseek+qwen来助力Solidworks二次开发
  • nigix面试常见问题(2025)
  • [GESP202312 六级] 工作沟通
  • 在工作中PostgreSQL常用的SQL命令
  • AJAX 简介
  • 【力扣Hot 100】堆
  • 典型的OSPF配置案例
  • 如何在 Vue 应用中实现权限管理?
  • 分布式与集群,二者区别是什么?
  • QT开发:事件循环与处理机制的概念和流程概括性总结
  • 王烨辉简历/小吴seo博客
  • 天长做网站的/宁波seo推广推荐
  • 扬州做网站哪家好/有趣软文广告经典案例
  • 做网站开发的想接私活/网站功能
  • 公司内部网站创建/网络营销推广公司网站
  • 宁波建设网站哪家好/亿驱动力竞价托管