微信小程序开发-个性化头像生成国庆渐变头像圣诞帽头像

author
2 minutes, 19 seconds Read

一、背景

今年国庆期间,渐变头像非常流行。 微信上的很多朋友都换了新的面貌。

查看源图像/

头像微信专用_微信专属头像_头像专属微信图片/

如上图,渐变头像。

作为一个程序员,当你看到上面的效果时,你首先会想到的是这是如何实现的? 我可以吗?

所以今天写这篇文章就是为了记录一下如何自己制作一个头像制作小工具。

废话不多说,下面是效果图。

国庆头像制作效果图:

国庆.gif/

脚步:

1.获取头像。

2.选择热门图片。

3.保存头像。

制作圣诞头像效果图:

圣诞.gif/

脚步:

1.获取当前微信用户头像。

2.选择你最喜欢的圣诞帽并调整圣诞帽的角度。

3. 保存图片。

好了,以上就是最终的效果了。 感兴趣的朋友可以扫描下方小程序二维码体验:

头像微信专用_头像专属微信图片_微信专属头像/

2. 实现原理

我们先介绍一下实现原理。 可以看到我们最终生成的头像是由两部分组成的。

微信头像+精选圣诞帽或国旗。

在小程序中,要实现这种将两张图片或者多张图片叠加在一起生成一张图片,使用

画布组件。

官方文档链接如下:

画布上下文 微信开放文档 微信开发者平台文档

/

我们这里主要用到两个API:

1)drawImage(imageResource,dx,dy,dWidth,dHeight)

将图像绘制到画布上

参数介绍:字符串imageResource

需要绘制的图片资源(必须先通过getImageInfo/downloadFile下载在线图片)

编号dx

imageResource的左上角位于目标画布的x轴位置

数数

imageResource 的左上角位于目标画布的 y 轴上。

数量 宽度

目标画布上绘制的 imageResource 的宽度,允许缩放绘制的 imageResource

数字 d 高度

绘制的 imageResource 在目标画布上的高度,允许缩放绘制的 imageResource

2)绘制(布尔保留,函数回调)

将先前在绘图上下文中的描述(路径、转换、样式)绘制到画布中。

参数布尔保留

此图是否遵循上一个图。 即如果reserve参数为false,则native层会先清空canvas,然后再继续本次绘制; 如果reserve参数为true,则保留当前canvas上的内容,并将这次drawCanvas绘制的内容覆盖在其上。 默认为 false。 。

函数回调

绘制完成后执行的回调函数

掌握了以上两个API后,就可以将两张图片叠加在一起了。

3. 代码实现

工程结构:

头像微信专用_微信专属头像_头像专属微信图片/

头像微信专用_头像专属微信图片_微信专属头像/

images:存储图像资源;

page:主要实现,国庆文件夹实现国庆头像的制作; chrismas文件夹实现圣诞头像的制作;

1)国庆头像制作代码

布局文件:guoqing.wxml



<viewstyle="margin-top:60px;margin-bottom:40px">
 <imagesrc="../../images/20190906-logo2.png"height="50px"class="header">image>
view>
<viewclass="hot-biz"style="width: 90%;margin: 0 auto;border-radius: 10px;margin-bottom:15px;"> 
 <viewclass="hot-top">
 <viewclass="tx">
 热门
 view>
 view>
 <viewclass="hot-item-list">
 <scroll-viewscroll-x>
 <viewclass="hot-biz-list" >
 <viewclass="item"wx:for="{{list}}"wx:key="id">
 <imagebindtap=selectImgdata-id={{item}}data-src=../../images/hat{{item}}.pngsrc="../../images/hat{{item}}.png"mode=aspectFill>image>
 view>
 view>
 scroll-view>
 view>
view>
<viewclass="canvas-view">
<viewstyle="width:150px;margin-left:20px;border: 2px solid #ffffff;">
 <canvascanvas-id="shareImg"style="width:150px;">canvas>
view>
 

<viewclass=canvas-view-right> 
 <buttonbindtap="getUserProfile"class="btn1">获取头像button>
 <buttonbindtap="save"class="btn1"disabled="{{!hasUserInfo}}">保存头像button>
 <buttonopen-type="share"bindtap=handleShareclass="btn1">分享好友button>
view>
view>

 

样式文件:guoqing.wxss

/* pages/guoqing/guoqing.wxss */
page{
 background: #FF5651;
 display: flex;
 flex-direction: column;
 align-items: center;
 align-content: center;
 }
 
 .header{
 width: 315px!important;
 height: 125px!important;
 }
 .canvas-view{
 width: 100%;
 align-content: center;
 align-items: center;
 text-align: center;
 display: flex;
 flex-direction: row;
 justify-content: space-between;
 }
 .canvas-view-right{
 display: flex;
 flex-direction: column;
 margin: 10px;
 }
 
 .btn1{
 background-color:#EB9A41;
 border-radius: 50px;
 color:#ffffff;
 width: 130px!important;
 height: 40px!important;
 font-size: 32rpx;
 height: 50rpx;
 display: flex;
 justify-content: center;
 margin-top: 10px;
 }
 
 /* list公共 */
 .hot-biz{
 margin-top: 10px;
 background: #fff;
 }
 .hot-biz.tx{
 font-size: 15px;
 margin-left: 10px;
 padding: 9px0;
 font-weight: 700;
 color: #FF5651;
 }
 .hot-top{
 display: flex;
 }
 
 /* 热门壁纸 */
 .hot-item-list{
 margin: 0 auto;
 width: 94%;
 margin-bottom: 20px;
 align-items: center;
 }
 .hot-biz-list { 
 display: flex; 
 justify-content: space-between; 
 height: 100%;
 align-items: center;
 /* flex-wrap: wrap; */
 }
 .hot-biz-list.item { 
 width: 50px; 
 flex-direction: column; 
 align-items: center; 
 height: 50px;
 padding-right: 8px;
 }
 .hot-biz-list image { 
 width: 50px; 
 height: 50px;
 border-radius:5px;
 margin: 0 auto;
 display: block;
 border:1px solid rgb(235, 235, 245);
 }
 /* end */

 

逻辑文件:guoqing.js

// pages/guoqing/guoqing.js
const ctx = wx.createCanvasContext(shareImg);
const app = getApp();
Page({
 /**
 * 页面的初始数据
 */
 data: {
 prurl: ,
 
 defaultImg: 0,
 
 userInfo: {},
 hasUserInfo: false,
 
 list: [
 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
 ]
 },
 
 selectImg: function(e){
 var current = e.target.dataset.id;
 console.log(current);
 this.setData({
 defaultImg: current,
 prurl: 
 });
 console.log("this:",this.data.userInfo);
 if(this.data.userInfo.avatarUrl){
 this.drawImg(this.data.userInfo.avatarUrl);
 } else {
 this.initCanvas(this.data.defaultImg);
 }
 },
 
 // 初始化
 initCanvas(index){
 let that = this;
 //主要就是计算好各个图文的位置
 let num = 150;
 // ctx.drawImage(res[0].path, 0, 0, num, num)
 ctx.drawImage(`../../images/hat${index}.png`, 0, 0, num, num)
 ctx.stroke()
 ctx.draw(false, () => {
 wx.canvasToTempFilePath({
 x: 0,
 y: 0,
 width: num,
 height: num,
 destWidth: 960,
 destHeight: 960,
 canvasId: shareImg,
 success: function(res) {
 that.setData({
 prurl: res.tempFilePath
 })
 // wx.hideLoading()
 },
 fail: function(res) {
 wx.hideLoading()
 }
 })
 })
 },
 
 
 // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
 // 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
 getUserProfile(e) {
 let that = this;
 if(!that.data.userInfo.avatarUrl){
 console.log(-- 1 --);
 wx.getUserProfile({
 desc: 仅用于生成头像使用, // 声明获取用户个人信息后的用途,后续会展示在弹窗。

 

Similar Posts