小程序中实现头像裁剪和拼接的效果

星空下的约定 2021-01-27 ⋅ 14 阅读

在小程序开发中,头像裁剪和拼接是常见的需求之一。本篇博客将介绍如何在小程序中实现头像裁剪的效果,并将多个头像拼接在一起。

1. 头像裁剪

前期准备

在小程序开发中,可以使用<image>标签来展示图片,同时可以使用wx.canvasContext来进行图片裁剪操作。首先,需要在小程序的开发者工具中创建一个新项目,然后新建一个页面用于实现头像裁剪效果。

页面结构

在创建的页面中,可以使用<image>标签来展示待裁剪的头像图片,并使用<canvas>标签来进行裁剪操作。页面结构如下:

<view class="container">
  <image src="{{avatarUrl}}" mode="aspectFill"></image>
  <canvas canvas-id="cropped" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd"></canvas>
</view>

JS代码实现

在页面的JS代码中,需要先选定待裁剪的头像图片,并定义裁剪框的初始位置和大小。然后,需要添加touchStarttouchMovetouchEnd事件监听器,以便能够在用户操作中动态改变裁剪框的位置和大小,并实时更新裁剪结果。代码示例如下:

Page({
  data: {
    avatarUrl: '', // 待裁剪头像的URL
    ctx: null, // 画布上下文
    startX: 0, // 裁剪框起始横坐标
    startY: 0, // 裁剪框起始纵坐标
    width: 0, // 裁剪框宽度
    height: 0, // 裁剪框高度
  },

  touchStart: function (e) {
    if (e.target.id === 'cropped') {
      const { x, y } = e.touches[0]
      // 记录起始位置
      this.data.startX = x
      this.data.startY = y
    }
  },

  touchMove: function (e) {
    if (e.target.id === 'cropped') {
      const { startX, startY } = this.data
      const { x, y } = e.touches[0]
      const { width, height } = this.data
      const context = this.data.ctx
      // 清空画布
      context.clearRect(0, 0, width, height)
      // 绘制裁剪框
      context.strokeStyle = 'red'
      context.strokeRect(startX, startY, x - startX, y - startY)
      context.stroke()
      // 更新裁剪框宽度和高度
      this.data.width = x - startX
      this.data.height = y - startY
    }
  },

  touchEnd: function (e) {
    if (e.target.id === 'cropped') {
      // 隐藏裁剪框
      const context = this.data.ctx
      context.clearRect(0, 0, this.data.width, this.data.height)
    }
  },

  onLoad: function (options) {
    // 初始化待裁剪头像URL
    this.setData({
      avatarUrl: options.avatarUrl
    })
    // 获取画布上下文
    const context = wx.createCanvasContext('cropped')
    this.setData({
      ctx: context
    })
  },
})

2. 头像拼接

前期准备

在小程序开发中,可以使用<view>标签作为容器来展示多个头像,并通过设置border-radiusborder属性来实现圆形头像和头像边框的效果。

页面结构

在已有的页面基础上,可以添加多个<image>标签来展示待拼接的头像图片。同时,可以设置一个<button>标签用于触发拼接功能。页面结构如下:

<view class="container">
  <image class="avatar" src="{{avatarList[0]}}" mode="aspectFill"></image>
  <image class="avatar" src="{{avatarList[1]}}" mode="aspectFill"></image>
  <button bindtap="mergeAvatar">拼接头像</button>
</view>

CSS样式

在CSS中,可以设置display: flex属性来让头像水平排列,并设置头像的圆角和边框样式。代码示例如下:

.container {
  display: flex;
}

.avatar {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  border: 4px solid #fff;
  margin-right: 10px;
}

JS代码实现

在页面的JS代码中,可以定义一个mergeAvatar函数来处理头像拼接的逻辑。在该函数中,可以使用wx.canvasContext将多个头像拼接成一张图片,并保存到本地。代码示例如下:

Page({
  data: {
    avatarList: [], // 待拼接头像的URL列表
  },

  mergeAvatar: function () {
    const ctx = wx.createCanvasContext('merged')
    const avatarList = this.data.avatarList

    // 加载并绘制头像图片
    for (let i = 0; i < avatarList.length; i++) {
      wx.getImageInfo({
        src: avatarList[i],
        success: (res) => {
          const avatarWidth = 100 // 头像图片的宽度
          const avatarHeight = 100 // 头像图片的高度

          // 使用源图像作为裁剪源,将圆形头像绘制在画布上
          ctx.save()
          ctx.beginPath()
          ctx.arc((avatarWidth / 2) + (avatarWidth + 10) * i, avatarHeight / 2 + 400, avatarWidth / 2, 0, Math.PI * 2)
          ctx.closePath()
          ctx.clip()
          ctx.drawImage(res.path, (avatarWidth + 10) * i, 400, avatarWidth, avatarHeight)
          ctx.restore()

          ctx.draw(true)
        }
      })
    }

    // 保存合成的图片到本地
    setTimeout(() => {
      wx.canvasToTempFilePath({
        canvasId: 'merged',
        success: function(res) {
          const tempFilePath = res.tempFilePath
          wx.saveImageToPhotosAlbum({
            filePath: tempFilePath,
             success(res) {
              wx.showToast({
                title: '保存成功',
                icon: 'success',
                duration: 2000
              })
            }
          })
        }
      })
    }, 1000)
  },

  onLoad: function (options) {
    // 初始化待拼接头像URL列表
    this.setData({
      avatarList: options.avatarList.split(',')
    })
  },
})

总结

通过使用小程序的<canvas>标签和wx.canvasContext,我们可以轻松实现头像裁剪和拼接功能。在裁剪功能中,通过监听用户的触摸事件,实时更新裁剪框的位置和大小。在拼接功能中,利用画布上下文wx.canvasContext将多个头像拼接成一张图片。这些功能可以为小程序开发中的头像处理需求提供便利和灵活性。


全部评论: 0

    我有话说: