likes
comments
collection
share

微信小程序中生成带个人二维码和头像的专属海报

作者站长头像
站长
· 阅读数 12

前言

先说一下开发背景,我们公司是做 IT 培训的,公司在各种节日的时候都会以海报的形式发布各种优惠活动,以促进更多的报名量,海报中带有公司的二维码,通过二维码就能联系到我们公司的客服小姐姐(效果看下图)

微信小程序中生成带个人二维码和头像的专属海报

但这样的宣传力度有限,毕竟没人帮你宣传,因为分享难(没)度(有)太(好)大(处),为了让更多的人参与其中并从受益,从而达到裂变的效果,公司提出了这么一个需求:开发一个生成海报功能,让用户能在海报中放上自己的专属二维码和头像

这样的好处是,通过你的海报报名的学生,你会从中得到一定的收益(想了解收益详情的可以联系我)。作为该活动的提出者,开发的任务自然就落到我的头上(我为什么要提出这活动方案!)

微信小程序中生成带个人二维码和头像的专属海报

硬着头皮上呗!主是之前没在小程序中做过类似这样的功能,我大概知道要用 Canvas 来实现,有想法就上

技术背景

原生微信小程序开发使用的技术就不用说了,wxmljavascriptjsonwxss (我还是说了!),

UI使用的有赞的vant-weapp,后端采用的是 云开发

小程序整体页面效果

微信小程序中生成带个人二维码和头像的专属海报

准备工作

在生成海报之前需要准备:海报图片,个人二维码图片以及头像图片

一、 获取海报信息

海报图片就用上面的海报,上面的客服二维码先不用管,一会我们用自己的二维码覆盖上去。

我的海报图片是放在小程序云存储中,所以在data中使用posterUrl存放地址就行,还需要获取二维码在海报中的位置,使用qrcodePosition存放

    Page({
        data:{
            posterUrl:'xxx', // 海报图片地址
            avatarUrl:'', // 头像图片地址
            qrcodeUrl:'' // 二维码图片地址
            qrcodePosition:{
                x: 185,
                y: 1540,
                width: 155,
                height: 155
            }
        }
        // ...
    })

二、 获取二维码信息

二维码一般由用户上传,使用wx.chooseMedia()让用户在相册中自行选择个人二维码

wxml结构代码如下:

    <van-cell title="我的二维码" label="点击右侧图标上传(默认小程序码)">
      <view slot="right-icon" class="pos-r">
        <van-button class="btn-qrcode" bind:tap="chooseQrcode">
          <van-image src="{{qrcodeUrl}}" width="40" height="40" wx:if="{{qrcodeUrl.length>0}}" />
          <van-icon name="qr" size="40" color="#ccc" wx:else />
        </van-button>
        <van-icon class="pos-a" name="clear" bind:tap="removeQRCode" wx:if="{{qrcodeUrl.length>0}}" />
      </view>
    </van-cell>

结构中做了个判断,用户没选择二维码时显示一个图标,选择后显示二维码图片和删除按钮,效果如下

微信小程序中生成带个人二维码和头像的专属海报

微信小程序中生成带个人二维码和头像的专属海报

JS代码如下:

    async chooseQrcode() {
        const {
            tempFiles
        } = await wx.chooseMedia({
            count: 1,
            mediaType: ['image']
        })

        this.setData({
            qrcodeUrl: tempFiles[0].tempFilePath
        })
    }

三、获取头像信息

头像获取使用微信的“头像选择”功能,让用户可以使用微信头像或相册中选取一张图片作为的头像,也可以现场自拍一张,效果如下:

微信小程序中生成带个人二维码和头像的专属海报

wxml结构代码如下:

    <van-cell title="我的头像" label="点击右侧图标获取微信头像">
      <view slot="right-icon" class="pos-r">
        <button class="btn-avatar" open-type="chooseAvatar" bind:chooseavatar="chooseAvatar">
          <van-image src="{{avatarUrl}}" width="40" height="40" wx:if="{{avatarUrl.length>0}}" />
          <van-icon name="user-circle-o" size="40" color="#ccc" wx:else />
        </button>
        <van-icon class="pos-a" name="clear" catch:tap="removeAvatar" wx:if="{{avatarUrl.length>0}}" />
      </view>
    </van-cell>

与二维码一样,wxml结构中做了个判断,用户没选择头像时显示一个图标,选择后显示头像图片和删除按钮,效果如下:

PS: 头像这里我还做了一样功能,当用户之前授权过头像获取时自动选择,从而减少用户的步骤

微信小程序中生成带个人二维码和头像的专属海报

微信小程序中生成带个人二维码和头像的专属海报

JS代码如下:

    chooseAvatar(e) {
        // 获取头像
        const {
            avatarUrl
        } = e.detail;
            this.setData({
            'avatarUrl': avatarUrl
        })
    }

四、获取画布信息

wxml中的代码

    <canvas type="2d" id="myPoster"></canvas>

小程序中没有DOM,不能用document获取页面元素,需要通过wx.createSelectorQuery()进行获取,同时还能获取canvas画布的宽高信息

js代码如下:

    const query = wx.createSelectorQuery()
    query.select('#myPoster')
    .fields({
        node: true,
        size: true
    })
    .exec(([res]) => {
        const canvas = res.node
        this.canvas = canvas;
        const ctx = canvas.getContext('2d')

        // 生成专属海报代码
        // ...
    })

五、生成海报

以上步骤全部完成后就可以开始生成海报了,先获取几张图片的信息,我们使用微信自带的wx.getImageInfo()获取海报图片的地址、宽高等信息

PS: 生成海报时需要时临时文件或者是本地文件,如果是网络图片,需要通过 wx.getImageInfo() 获取图片的临时路径

1. 获取海报图片信息

    const posterInfo = await wx.getImageInfo({
        src: posterUrl,
    });

2. 获取二维码图片信息

    const qrcodeInfo = await wx.getImageInfo({
        src: qrcodeUrl,
    })

3. 获取头像图片信息

    const avatarInfo = await wx.getImageInfo({
        src: avatarUrl,
    })

4. 开始生成带二维码和头像的专属海报

接着就可以利用canvas画布按我们的需求生成专属海报了(以下代码接着上面四、获取画布信息的代码继续编写)

1)根据海报高度自动调节canvas高度

PS:需要使用设备像素比来调节画布大小,否则 canvas 保存的图片会很模糊,我们需要对 canvas 画布进行多倍处理

    // 1.根据海报高度自动调节canvas高度
    const canvasHeight = res.width * posterInfo.height / posterInfo.width
    const dpr = wx.getSystemInfoSync().pixelRatio
    canvas.width = res.width * dpr
    canvas.height = canvasHeight * dpr
    ctx.scale(dpr, dpr)
    
    // 2.绘制海报
    // ...
2)绘制海报
    // 2.绘制海报
    const posterImg = canvas.createImage()
    posterImg.src = posterInfo.path
    posterImg.onload = () => {
        ctx.drawImage(posterImg, 0, 0, res.width, canvasHeight)

        // 3. 绘制二维码
        // ...
    }
3)绘制二维码
    // 3.绘制二维码
    const qrcodeImg = canvas.createImage()
    qrcodeImg.src = qrcodeInfo.path
    qrcodeImg.onload = () => {
        // 计算海报缩放比例
        const ratio = res.width / posterInfo.width

        // 获取海报中二维码的位置及大小
        const {
            x,
            y,
            width,
            height
        } = qrcodePosition;

        // 根据缩放比例和原大小计算精确二维码绘制位置
        const qrcX = x * ratio
        const qrcY = y * ratio
        const qrcW = width * ratio
        const qrcH = height * ratio
        ctx.drawImage(qrcodeImg, qrcX, qrcY, qrcW, qrcH)

        // 4. 绘制头像
        // ...
    }
4)绘制头像
    // 4. 绘制头像
    const avatarImg = canvas.createImage()
    avatarImg.src = avatarInfo.path
    avatarImg.onload = () => {
        // 计算二维码缩放比例
        const ratio = qrcW / qrcodeImg.width

        // 根据缩放比例和原大小计算精确头像绘制位置
        const aW = 170 * ratio
        const aH = 170 * ratio
        const aX = qrcX + qrcW / 2 - aW / 2
        const aY = qrcY + qrcH / 2 - aH / 2
        ctx.drawImage(avatarImg, aX, aY, aW, aH)
    }

5. 最终海报效果

微信小程序中生成带个人二维码和头像的专属海报

图片效果可能看得不是很清楚,大家可以搜索趣学旅程小程序测试效果(也可以扫下小程序码进入)

微信小程序中生成带个人二维码和头像的专属海报

六、输出图片保存并分享

使用wx.canvasToTempFilePath()从canvas中输出图片,得到一个临时地址,还需要通过wx.saveImageToPhotosAlbum()保存到相册,JS代码如下:

    async savePoster() {
        const {
            tempFilePath
        } = await wx.canvasToTempFilePath({
            canvas: this.canvas
        })

        wx.saveImageToPhotosAlbum({
            filePath: tempFilePath,
        success() {
            wx.showToast({
                title: '保存成功',
                icon: 'none'
            })
        }
        })
    }

PS:分享功能设置好小程序的onShareAppMessage就可以了,这里就不展开了,小伙伴们请自行处理

结语

好了,如何在微信小程序中生成带个人二维码和头像的教程就写到这,有问题的小伙伴欢迎在评论区讨论,最后附上我生成的专属海报,后面会继续推出一些实用的教程,请继续关注

微信小程序中生成带个人二维码和头像的专属海报