保姆级教学 uniapp绘制二维码海报并保存至相册,真机正常展示图片二维码

一、获取二维码

javascript 复制代码
      uni.request({
        url: `https://api.weixin.qq.com/wxa/getwxacode?access_token=${getStorage("token")}`,
        responseType: "arraybuffer",
        method: "POST",
        data: {
          path: "/pages/index/index"
        },
        success(res) {
          // 转换为 Uint8Array 类型的数组
          const arrayBuffer = new Uint8Array(res.data)

          // 转换为 Base64 编码的字符串
          const base64 = uni.arrayBufferToBase64(arrayBuffer)

          // 缓存至本地
          state.image = base64
        },
        fail(err) {
          console.log(err, "err")
        }
      })

代码仅作示例

以上代码作用就是,拿到后端给的base64格式的图片,用做绘图

二、绘制画布

javascript 复制代码
    const handleCanvas = () => {
      //初始化画布
      const ctx = uni.createCanvasContext('myCanvas');
      ctx.setFillStyle("rgba(96, 216, 254, 1)")
      ctx.fillRect(0, 0, uni.upx2px(750), uni.upx2px(1120))

      //外边框
      const mx = uni.upx2px(55)
      const my = uni.upx2px(332);
      const mwidth = uni.upx2px(640);
      const mheight = uni.upx2px(640);
      const mradius = uni.upx2px(32);
      const mColor = "#DFF3FF"
      _border(ctx, mx, my, mwidth, mheight, mradius, mColor)

      // 内边框
      const px = uni.upx2px(105)
      const py = uni.upx2px(382);
      const pwidth = uni.upx2px(540);
      const pheight = uni.upx2px(540);
      const pradius = uni.upx2px(32);
      const pColor = "#FFF"
      _border(ctx, px, py, pwidth, pheight, pradius, pColor)

      //二维码  
      _QRCode(ctx, state.image)
        
      // 绘制画布
      ctx.draw()
    }


     // 绘制边框   参数分别为  画布对象 画布x轴起点 画布y轴起点 画布宽度 画布高度 圆角边框 背景色
    const _border = (ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number, color: string) => {
      ctx.beginPath();
      ctx.moveTo(x + radius, y);
      ctx.lineTo(x + width - radius, y);
      ctx.arcTo(x + width, y, x + width, y + radius, radius);
      ctx.lineTo(x + width, y + height - radius);
      ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);
      ctx.lineTo(x + radius, y + height);
      ctx.arcTo(x, y + height, x, y + height - radius, radius);
      ctx.lineTo(x, y + radius);
      ctx.arcTo(x, y, x + radius, y, radius);
      ctx.closePath();
      ctx.fillStyle = color;
      ctx.fill();
    }


    const _QRCode = (ctx, data) => {
      // 获取文件管理器
      const fsm = wx.getFileSystemManager();

      //  将 base64 字符串转成 ArrayBuffer对象
      const buffer = wx.base64ToArrayBuffer(data);

      // 文件系统中的用户目录路径 (本地路径)
      const fileName = wx.env.USER_DATA_PATH + '/share_img.png';

      fsm.writeFileSync(fileName, buffer, 'binary'); // 写入文件, 同步方法

      // 以上四行代码让其在真机上正常显示,因为canvas无法读取base64格式,需要先保存在文件管理器,拿到临时路径

      ctx.drawImage(fileName, uni.upx2px(135), uni.upx2px(412), uni.upx2px(480), uni.upx2px(480))
    }

1.复杂样式尽量使用图片引入ctx.drawImage("换成你本地图片的相对路径",...)

2.需要其他样式或者图片,自行添加,我这个应该还有个背景图的,在等UI出图

3.画布绘制的顺序需要注意下,后面覆盖的图形会把前面的图形在视觉上覆盖掉,所以二维码方法要写在最后面

三、保存至相册

javascript 复制代码
    const handleSave = () => {
      uni.showLoading({
        title: '正在生成海报',
        mask: true
      })
      uni.canvasToTempFilePath({
        canvasId: 'myCanvas',
        success: (res) => {
          uni.saveImageToPhotosAlbum({
            filePath: res.tempFilePath,
            success: (res) => {
              uni.showToast({
                title: '保存成功',
                icon: 'none'
              })
            }
          })
        },
        complete(result) {
          uni.hideLoading()
        },
      })
    }
相关推荐
七七小报34 分钟前
uniapp-商城-54-后台 新增商品(页面布局)
uni-app
HebyH_3 小时前
2025前端面试遇到的问题(vue+uniapp+js+css)
前端·javascript·vue.js·面试·uni-app
gys989512 小时前
android studio开发aar插件,并用uniapp开发APP使用这个aar
android·uni-app·android studio
自然 醒17 小时前
荣耀手机,系统MagicOS 9.0 USB配置没有音频来源后无法被adb检测到,无法真机调试的解决办法
adb·uni-app
*拯1 天前
Uniapp Android/IOS 获取手机通讯录
android·ios·uni-app
gaojianqiao12341 天前
uniapp引入七鱼客服微信小程序SDK
微信小程序·uni-app
zhangzuying10261 天前
在uni-app中实现类似文心一言的流式对话功能:从fetch到websocket的实践
websocket·uni-app·文心一言
假客套1 天前
2025 后端自学UNIAPP【项目实战:旅游项目】3、API接口请求封装,封装后的简单测试以及实际使用
uni-app·旅游项目实战
JAVA叶知秋2 天前
uniapp自定义底部导航栏h5有效果小程序无效的解决方案
小程序·uni-app
moxiaoran57532 天前
uni-app学习笔记(二)--vue页面代码的构成和新建页面
笔记·学习·uni-app