【微信小程序】实现生成图片分享朋友圈

本文介绍如何在微信小程序中利用Canvas绘制图片并保存至相册以便分享至朋友圈。文章详细展示了从下载背景图片、绘制元素到最终保存图片的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

目前小程序只支持卡片方式分享到聊天页面,官方不知道何时会新增分享朋友圈方式。最近有个需求要分享到朋友圈,现在大家的通用做法就是通过Canvas生成一张图片后进行保存,然后自行转发朋友圈。最近有个此类需求,至此把开发过程中遇到的坑做个记录,下面先看下效果图。


踩坑记录

1、在开发过程中,使用了微信的下载文件API,所以需要在小程序后台downloadFile合法域名配置 <<图片域名>> 的白名单(配置后有时间延迟,所以需要耐心等待)。但是,不管是在微信开发工具中还是真机开启调试模式时候,不配置下载域名白名单功能也是正常。所以记得配置。

2、下载图片后,一定要通过wx.getImageInfo 来获取到图片的信息。不然真机上无法获取到图片信息,Canvas 无法绘制。

目前通过Canvas绘制出来的文字和图片还有些模糊,有抗锯齿。接下来将会优化,然后再进行补充说明。

在这里插入图片描述
在这里插入图片描述

实现

1、打卡成功后后台返回数据,下载要绘制的图片

生命周期OnShow()方法里调用


  showPoster: function() {
      this.setData({
        showPoster: false
      })
      wx.downloadFile({
        url: this.data._posterBackground,
        success: (res) => {
          this.setData({
            downloadPosterBg: res.tempFilePath
          })
        }
      })
      // 下载头像
      wx.downloadFile({
        url: this.data._posterHeadImage,
        success: (res) => {
          this.setData({
            downloadHeaderImage: res.tempFilePath
          })
        }
      })
      wx.downloadFile({
        url: this.data._posterDakaOrgLogo,
        success: (res) => {
          this.setData({
            downloadOrgLogo: res.tempFilePath
          })
        }
      })
      wx.downloadFile({
        url: this.data._posterQRImage,
        success: (res) => {
          this.setData({
            downloadQRImage: res.tempFilePath
          })
        }
      })
    },
    

2、获取保存图片到系统相册到权限


    getPosterScope () {
      wx.getSetting({
        success: (res) => {
          if (res.authSetting['scope.writePhotosAlbum'] != undefined && res.authSetting['scope.writePhotosAlbum'] != true) {
            //非初始化进入该页面,且未授权
            wx.showModal({
              title: '是否授权保存图片到系统相册',
              content: '请确认授权,否则无法保存图片到系统相册',
              success: (res) => {
                if (res.cancel) {
                  utils.showToast('none', '授权失败')
                } else if (res.confirm) {
                  wx.openSetting({
                    success: (dataAu) => {
                      if (dataAu.authSetting["scope.writePhotosAlbum"] == true) {
                        utils.showToast('none', '授权成功')
                        this.savePoster();
                      } else {
                        utils.showToast('none', '授权失败')
                      }
                    }
                  })
                }
              }
            })
          } else if (res.authSetting['scope.writePhotosAlbum'] == undefined) {
            //初始化进入
            this.savePoster();
          }
          else { 
            //授权后默认加载
            this.savePoster();
          }
        }
      })
    },

2、点保存图片,Canvas绘图


    savePoster () {
      // 获取下载下来图片信息
      let {downloadPosterBg, downloadHeaderImage, downloadOrgLogo, downloadQRImage, _posterNickName, _posterDakaName, _posterDakaCount, _posterDakaOrgName} = this.data
      wx.showLoading({
        title: '分享图片生成中...',
        icon: 'loading',
        duration: 5000
      })
      let isImgDownloaded = downloadPosterBg != '' && downloadHeaderImage != '' && downloadOrgLogo != '' && downloadQRImage != ''
      if (isImgDownloaded) {
        /* 图片获取成功才执行后续代码 */
        let canvas = wx.createCanvasContext('hoCanvas', this)

        let rpxToPx = this.data.rpxToPx
        // 绘制背景图
        canvas.drawImage(downloadPosterBg, 0, 0, 632 * rpxToPx, 970 * rpxToPx);
        // 绘制头像
        canvas.save()
        canvas.beginPath()
        canvas.arc(74 * rpxToPx, 741 * rpxToPx, 36 * rpxToPx, 0, 2 * Math.PI)
        canvas.clip()
        canvas.drawImage(downloadHeaderImage, 38 * rpxToPx, 705 * rpxToPx, 72 * rpxToPx, 72 * rpxToPx);
        canvas.restore()

        // 绘制机构logo
        canvas.save()
        canvas.beginPath()
        canvas.arc(74 * rpxToPx, 881 * rpxToPx, 36 * rpxToPx, 0, 2 * Math.PI)
        canvas.clip()
        canvas.drawImage(downloadOrgLogo, 38 * rpxToPx, 845 * rpxToPx, 72 * rpxToPx, 72 * rpxToPx);
        canvas.restore()

        // 绘制班级二维码
        canvas.drawImage(downloadQRImage, 492 * rpxToPx, 833 * rpxToPx, 100 * rpxToPx, 100 * rpxToPx);

        //绘制微信昵称文本
        canvas.setFontSize(28 * rpxToPx)
        canvas.setFillStyle("#000")
        canvas.setStrokeStyle('#000')
        canvas.fillText(_posterNickName, 120 * rpxToPx, 735 * rpxToPx)

        // 绘制打卡昵称
        canvas.setFontSize(24 * rpxToPx)
        canvas.setFillStyle("#000")
        canvas.setStrokeStyle('#000')
        canvas.fillText(_posterDakaName, 120 * rpxToPx, 775 * rpxToPx)

        // 绘制坚持天数
        canvas.setFontSize(38 * rpxToPx)
        canvas.setFillStyle("#000")
        canvas.setStrokeStyle('#000')
        if (_posterDakaCount <= 9) {
          canvas.fillText(_posterDakaCount, 470 * rpxToPx, 777 * rpxToPx)
        } else if (_posterDakaCount > 9 && _posterDakaCount < 99) {
          canvas.fillText(_posterDakaCount, 470 * rpxToPx, 777 * rpxToPx)
        } else if (_posterDakaCount> 99 && _posterDakaCount < 999) {
          canvas.fillText(_posterDakaCount, 470 * rpxToPx, 777 * rpxToPx)
        }

        //绘制机构名称(or 君早安)
        canvas.setFontSize(28 * rpxToPx)
        canvas.setFillStyle("#000")
        canvas.setStrokeStyle('#000')
        canvas.fillText(_posterDakaOrgName, 120 * rpxToPx, 875 * rpxToPx)

        canvas.setFontSize(24 * rpxToPx)
        canvas.setFillStyle("#000")
        canvas.setStrokeStyle('#000')
        canvas.fillText('用习惯问早安  每天进步一点点', 120 * rpxToPx, 915 * rpxToPx)

        canvas.draw(true,setTimeout( () => {
          wx.canvasToTempFilePath({
            x: 0,
            y: 0,
            width: 632 * rpxToPx,
            height: 970 * rpxToPx,
            destWidth: 632 * rpxToPx,
            destHeight: 970 * rpxToPx,
            canvasId: 'hoCanvas',
            success: (res) => {
              this.saveImageToAlbum(res.tempFilePath);
              wx.hideLoading()
            },
            fail:  (res) => { utils.showToast('none', '网络错误,请稍后再试') }
          }, this)
      },1000))
      }
    },

4、调用微信API,将图片保存到相册

   
    saveImageToAlbum (postUrl) {
      wx.saveImageToPhotosAlbum({
        filePath: postUrl,
        success: (res) => {
          wx.showModal({
            title: '保存成功',
            content: '图片成功保存到相册了,快去分享朋友圈吧',
            showCancel: false,
            confirmText: '好的',
            confirmColor: '#818FFB',
            success: (res) => {
              if (res.confirm) {
                this.setData({
                  showPoster: true
                })
              }
            }
          })
        }
      })
    },
    

结尾

~~

评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值