微信小程序:生成自定义海报并保存到本地和生成带logo和Id的二维码

这周做项目的时候分到一个新的需求说要生成一张海报,用户保存图片到本地分享
而且对二维码有要求:生成一个小程序码和一个二维码,且生成的二维码需要带有用户ID
完成后有空闲时间分享出来
代码如下:

import QRCode from '../../utils/plugins/weapp.qrcode.js'
// import QRCode from '../../utils/plugins/weapp-qrcode.js' 不带logo的二维码
Page({
    
    

  /**
   * 生成二维码:
   * 生成带参数id的二维码,由app端用户扫码,app获取参数
   * 生成小程序码,用户扫码进入指定小程序页面
   */
  data: {
    
    
    imagePath: "",
    maskHidden: false,
    user_img: 'https://img0.baidu.com/it/u=1835384573,4158682262&fm=11&fmt=auto&gp=0.jpg',
    qrcode_image: '',
  },

  onShow: function () {
    
    
    var that = this;
    wx.showLoading({
    
    
      title: '二维码生成中...',
      mask: true
    })

    this.getQRCode()

    // that.qrcode_image();
    wx.getImageInfo({
    
    
      src: this.data.qrcode_image,
      success(res) {
    
    
        console.log("二维码:" + res.path);
        that.setData({
    
    
          qrcode_image: res.path,
        })
      }
    })
    wx.getImageInfo({
    
    
      src: that.data.user_img,
      success(res) {
    
    
        console.log("头像:" + res.path);
        that.setData({
    
    
          user_img: res.path
        })
      }
    })
  },

  // 生成不带logo的二维码(用户app扫码获取id)
  // getQRCode() {
    
    
  //   new QRCode('myQrcode', {
    
    
  //     image: { imageResource: '../../assets/images/[email protected]', dx: 0, dy: 0, dWidth: 100, dHeight: 100 },
  //     text: this.data.userInfo.Id, // 传递的数据
  //     width: 200,
  //     height: 200,
  //     padding: 0, // 生成二维码四周自动留边宽度,不传入默认为0
  //     correctLevel: QRCode.CorrectLevel.L, // 二维码可辨识度
  //     callback: (res) => {
    
    
  //       console.log(res.path)
  //       this.data.qrcode_image = res.path
  //       // 接下来就可以直接调用微信小程序的api保存到本地或者将这张二维码直接画在海报上面去,看各自需求
  //     },
  //   })
  // },
  
// 生成带logo的二维码
  getQRCode() {
    
    
    QRCode({
    
    
      image: {
    
    
        imageResource: '../../assets/images/log_icon_logo.png',// svg图再真机测试会出不来,换成png的可以,且只能是本地图片
        dx: 71.5,
        dy: 71.5,
        dWidth: 57,
        dHeight: 57
      },
      text: this.data.userInfo.Id, // 传递的数据,获取不到则不能生成二维码
      width: 200,
      height: 200,
      canvasId: 'myQrcode',
      _this: this,
      callback: () => {
    
    
        setTimeout(() => {
    
    
          wx.canvasToTempFilePath({
    
    
            canvasId: 'myQrcode',
            success: res => {
    
    
              console.log(res.tempFilePath)
              this.setData({
    
    
                qrcode_image: res.tempFilePath
              })
            }
          }, this)
        }, 500)
      },
    })
  },

  //点击生成海报
  formSubmit: function (e) {
    
    
    var that = this;
    wx.showToast({
    
    
      title: '海报生成中...',
      icon: 'loading',
      duration: 1000
    });
    that.createNewImg();
    setTimeout(function () {
    
    
      wx.hideToast()
      that.setData({
    
    
        maskHidden: true
      });
    }, 1000);
  },
  //将canvas转换为图片保存到本地,然后将图片路径传给image图片的src
  createNewImg: function () {
    
    
    var that = this;
    
    // 创建画布
    var context = wx.createCanvasContext('mycanvas');
    context.clearRect(0, 0, 375, 800);
    context.setFillStyle("#fff")
    context.fillRect(0, 0, 375, 800)
    context.save(); //保存之前的画布设置


    // 绘制渐变背景
    var lg1 = context.createLinearGradient(0, 0, 0, 400);
    // 参数:x0:渐变开始点的 x 坐标,
    // 参数:y0:渐变开始点的 y 坐标,
    // 参数:x1:渐变结束点的 x 坐标,
    // 参数:y1:渐变结束点的 y 坐标
    lg1.addColorStop(0, '#2869FF');
    lg1.addColorStop(1, '#FFFFFF');
    context.fillStyle = lg1;
    context.beginPath();
    context.fillRect(6, 50, 363, 407);
    context.save();

    // 绘制渐变按钮
    var lg2 = context.createLinearGradient(0, 0, 410, 0);
    // 参数:x0:渐变开始点的 x 坐标,
    // 参数:y0:渐变开始点的 y 坐标,
    // 参数:x1:渐变结束点的 x 坐标,
    // 参数:y1:渐变结束点的 y 坐标
    lg2.addColorStop(0, '#4C7CFF');
    lg2.addColorStop(1, '#315AD8');
    context.fillStyle = lg2;
    context.beginPath();
    context.fillRect(6, 437, 363, 40);
    context.save(); //保存之前的画布设置

    // 获取图片路径
    var path1 = that.data.qrcode_image;
    console.log("营销员二维码" + path1);
    // var path2 = that.data.qrcode_image;
    // console.log("小程序二维码" + path2);
    var path3 = that.data.user_img;
    console.log("用户头像" + path3);

    // 绘制标题
    context.setFontSize(20);
    context.setFillStyle('#fff');
    context.setTextAlign('left');
    context.font = 'normal bold 20px sans-serif';
    context.fillText("- 扫描二维码关联营销员 -", 68.5, 110);// context.fillText(text,x,y,maxWidth);
    context.stroke();
    context.save();


    // 绘制按钮黄色背景
    context.fillStyle = "#FFB73F";
    context.beginPath();
    context.fillRect(188, 445, 23, 22);
    context.save(); //保存之前的画布设置

    // 绘制文字
    var titl = "荀彧";
    context.setFontSize(20);
    context.setFillStyle('#fff');
    context.setTextAlign('left');
    context.font = 'normal bold 20px sans-serif';
    context.fillText(titl, 184, 152);
    context.stroke();
    context.save();

    var tit2 = "测";
    context.setFontSize(20);
    context.setFillStyle('#fff');
    context.setTextAlign('left');
    context.font = 'normal bold 20px sans-serif';
    context.fillText(tit2, 165, 464);
    context.stroke();
    context.save();

    var tit2 = "试";
    context.setFontSize(20);
    context.setFillStyle('#315AD8');
    context.setTextAlign('left');
    context.font = 'normal bold 20px sans-serif';
    context.fillText(tit2, 190, 464);
    context.stroke();
    context.save();

    // 绘制头像
    context.beginPath();
    context.arc(162, 144, 16, 0, 2 * Math.PI);
    context.setStrokeStyle("#44bf8c");
    context.clip(); //裁剪上面的圆形
    context.drawImage(path3, 146, 128, 34, 34); // 此处的x,y相对于arc的x,y
    context.restore();
    context.closePath();
    context.save(); //保存之前的画布设置

    // 绘制二维码
    context.drawImage(path1, 86, 184, 203, 203);
    context.save(); //保存之前的画布设置

    context.draw(true);//true表示保留之前绘制内容

    //将生成好的图片保存到本地,需要延迟一会,绘制期间耗时
    setTimeout(function () {
    
    
      wx.canvasToTempFilePath({
    
    
        canvasId: 'mycanvas',
        success: function (res) {
    
    
          var tempFilePath = res.tempFilePath;
          that.setData({
    
    
            imagePath: tempFilePath
          });
        },
        fail: function (res) {
    
    
          console.log(res);
        }
      });
    }, 1000);
  },

  //点击保存到相册
  baocun: function () {
    
    
    var that = this
    wx.saveImageToPhotosAlbum({
    
    
      filePath: that.data.imagePath,
      success(res) {
    
    
        wx.showToast({
    
    
          title: '图片已保存到相册',
          icon: 'none',
          duration: 2000
        })
        that.setData({
    
    
          maskHidden: false
        })
      },
      fail(){
    
    
        that.setData({
    
    
          maskHidden: false
        })
      }
    })
  },

  qrcode_image: function () {
    
    
    let that = this;
    wx.request({
    
    
      url: 'https://api.weixin.qq.com/cgi-bin/token',
      data: {
    
    
        grant_type: 'client_credential',
        appid: '', //不能缺少
        secret: '' //不能缺少
      },
      success: function (res) {
    
    
        wx.request({
    
    
          url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + res.data.access_token,
          data: {
    
    
            "path": "pages/index/index", //默认跳转到主页:pages/index/index,可指定
            "width": 200,
            "scene": "type=0&evaId=" + that.data.id,
          },
          responseType: 'arraybuffer', // 这行很重要,转为二进制数组
          header: {
    
    
            'content-type': 'application/json;charset=utf-8'
          },
          method: 'POST',
          success(res) {
    
    
            //转为base64
            let bin64 = wx.arrayBufferToBase64(res.data);

            that.setData({
    
    
              //base 64设置到页面上
              qrcode_image: "data:image/png;base64," + bin64
            });
          }
        })
      }
    })
  }
})

页面代码如下:

<view class="code_container">
  <view class="code_box">
    <view class="code_tit">- 扫描二维码关联营销员 -</view>
    <view class="code_info">
      <image src="{
     
     {user_img}}" mode="aspectFill"></image>
      <text class="code_name">荀彧</text>
    </view>
    <canvas
      hidden="{
     
     {maskHidden == true}}"
      class="code_img"
      canvas-id="myQrcode"
      style="background:#fff;width: 200px;height: 200px;z-index:1"
    />
  </view>
  <view class="code_btn" bindtap="formSubmit">保存到相册</view>
</view>

<view class='imagePathBox' hidden="{
     
     {maskHidden == false}}">
  <image src="{
     
     {imagePath}}" class='shengcheng'></image>
  <view class="save_img" bindtap="baocun">点击保存相册吧</view>
</view>
<view hidden="{
     
     {maskHidden == false}}" class="mask"></view>
<view class="canvas-box">
  <canvas style="width:375px;height:670px;position:fixed;top:9999px" canvas-id="mycanvas" />
</view>


样式代码如下:

/* pages/code/code.wxss */
page {
    
    
  background: #EDEDED;
}


.imagePathBox {
    
    
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
}

.mask {
    
    
  width: 100%;
  height: 100%;
  /* background: rgba(0,0,0,0.7); */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9000;
}

.shengcheng {
    
    
  width: 80%;
  height: 80%;
  position: fixed;
  top: 50rpx;
  left: 50%;
  margin-left: -40%;
  z-index: 10;
}


.shareFriends {
    
    
  display: block;
  width: 80%;
  height: 104rpx;
  padding: 0;
  line-height: 80rpx;
  text-align: center;
  position: fixed;
  bottom: 50rpx;
  left: 10%;
  background: #45be8d;
  color: rgb(211, 208, 208);
  font-size: 32rpx;
  border-radius: 44rpx;
}


button[class="baocun"]::after {
    
    
  border: 0;
}

/* canvas绘图 */
/* .canvas-box{
  width:0rpx;
  height:0rpx;
  overflow: hidden;
  position: fixed;
  left:0rpx;
  bottom:30rpx;
  z-index: 9999;
} */
.code_container {
    
    
  padding: 20rpx 12rpx;
}

.code_box {
    
    
  display: flex;
  flex-direction: column;
  background-image: linear-gradient(180deg, #4C7CFF 10%, #FFFFFF 73%, #FFFFFF 99%);
  border-radius: 16rpx;
  justify-content: center;
  align-items: center;
  padding: 60rpx 0 50rpx;
}

.code_tit {
    
    
  font-size: 40rpx;
  color: #FFFFFF;
  font-weight: 700;
}

.code_info {
    
    
  margin-top: 28rpx;
  height: 65rpx;
  line-height: 65rpx;
  display: flex;
  justify-content: center;
}
.code_name {
    
    
  font-size: 40rpx;
  color: #FFFFFF;
  font-weight: 700;
  margin-left: 12rpx;
}

.code_info image {
    
    
  width: 64rpx;
  height: 64rpx;
  border-radius: 50%;
}

.code_img {
    
    
  width: 406rpx;
  height: 406rpx;
  border-radius: 4rpx;
  margin-top: 60rpx;
}

.code_btn{
    
    
  background: #4C7CFF;
  border-radius: 54rpx;
  width: 566rpx;
  height: 108rpx;
  line-height: 108rpx;
  text-align: center;
  color: #fff;
  font-size: 34rpx;
  font-weight: 700;
  margin: 60rpx auto 0;
}

.save_img{
    
    
  background: #4C7CFF;
  border-radius: 6rpx;
  font-size: 30rpx;
  font-weight: 400;
  width: 80%;
  height: 80rpx;
  padding: 0;
  line-height: 80rpx;
  text-align: center;
  position: fixed;
  bottom: 80rpx;
  left: 10.5%;
  color: #fff;
}

运行效果如下:
在这里插入图片描述

苹果X保存效果:
在这里插入图片描述


测试运行是没有什么问题的

猜你喜欢

转载自blog.csdn.net/weixin_33538887/article/details/118572131