小程序,canvas绘制图片,且把图片保存下来

617 阅读3分钟

最近做一个功能,是在小程序里保存图片,因为本身内容不是图片,所以只能把内容绘画成图片,才能保存下来,

这是跟我们需求写的页面效果:

下面是实现的代码:

wxml部分

<button bindtap="cartridge">显示图片</button>

<!-- 弹窗 -->
<view class='imagePathBox' hidden="{{maskHidden}}">
  <image src="{{imagePath}}" mode="aspectFill" class='canvas-img'></image>
  <button class='saveBtn' bindtap='saveBtn'>保存到手机</button>
  <view class='remind'>您的信息仅会保留1个月,请及时保存哦~</view>
  <view>
    <image src="../../images/close.png" class='close' bindtap='closeBtn'></image>
  </view>
  <view hidden="{{maskHidden == false}}" class="mask"></view>
  <view class="canvas-box">
    <canvas style="width: 375px;height: 667px;position:fixed;top:9999px;" canvas-id="mycanvas" />
  </view>
</view>

js部分

Page({

  /**
   * 页面的初始数据
   */
  data: {
    maskHidden: true,
    date: '2019-08-30',
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  // 显示图片
  cartridge() {
    const that = this;
    wx.showToast({
      title: '生成中...',
      icon: 'loading',
      duration: 1000
    });
    setTimeout(function () {
      wx.hideToast()
      that.createNewImg();
      that.setData({
        maskHidden: false
      });
    }, 2000)

  },

  // 创建图片内容
  createNewImg: function () {
    const that = this;
    const content = "兹证明 张三(先生/女生)于 " + that.data.date + " 参加国际交流中心小程序培训,通过考试,成绩合格。"
    that.setData({
      content: content
    })
    const context = wx.createCanvasContext('mycanvas');
    context.fillRect(0, 0, 375, 667) //绘制区域,和wxml的画布大小一致
    const imgPath = '../../images/bj.jpg';  //添加背景图片
    context.drawImage(imgPath, 0, 0, 375, 667);
    //绘制标题
    context.setFontSize(40);
    context.setFillStyle('#ff5b89');
    context.setTextAlign('center');
    context.fillText("合格证书", 185, 113);
    context.stroke();

    // 绘制内容
    context.setFontSize(18);
    context.setFillStyle('#333333');
    context.setTextAlign('left');
    that.drawText(context, that.data.content, 22, 182, 330, 330)
    context.stroke();
    // 结束语
    context.setFontSize(18);
    context.setFillStyle('#333333');
    context.setTextAlign('right');
    context.fillText("国际合作交流中心", 360, 348);
    context.fillText(that.data.date, 360, 373);
    context.stroke();
    // 绘图的命令
    context.draw();
    //将生成好的图片保存到本地,需要延迟一会,绘制期间耗时
    setTimeout(function () {
      wx.canvasToTempFilePath({
        canvasId: 'mycanvas',
        success: function (res) {
          const tempFilePath = res.tempFilePath;
          that.setData({
            imagePath: tempFilePath,
            canvasHidden: true
          });
        },
        fail: function (res) {
          console.log(res);
        }
      });
    }, 200);
  },

  //文本换行 参数:1、canvas对象,2、文本 3、距离左侧的距离 4、距离顶部的距离 5、6、文本的宽度
  drawText: function (ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) {
    let lineWidth = 0;
    let lastSubStrIndex = 0; //每次开始截取的字符串的索引
    for (let i = 0; i < str.length; i++) {
      lineWidth += ctx.measureText(str[i]).width;
      if (lineWidth > canvasWidth) {
        ctx.fillText(str.substring(lastSubStrIndex, i), leftWidth, initHeight); //绘制截取部分
        initHeight += 30; //30为字体的高度,//行间距
        lineWidth = 0;
        lastSubStrIndex = i;
        titleHeight += 30;
      }
      if (i == str.length - 1) { //绘制剩余部分
        ctx.fillText(str.substring(lastSubStrIndex, i + 1), leftWidth, initHeight);
      }
    }
    // 标题border-bottom 线距顶部距离
    titleHeight = titleHeight + 10;
    return titleHeight
  },
  closeBtn() {
    this.setData({
      maskHidden: true
    })

  }

})

css部分:

/* 需要绘制的画布 */

.imagePathBox {
  width: 100%;
  height: 100%;
  background: rgba(55, 60, 81, 0.8);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
}

/* 生成的图片--白色区域 */

.canvas-img {
  width: 80%;
  height: 75%;
  position: fixed;
  top: 50rpx;
  left: 50%;
  margin-left: -40%;
  z-index: 10;
  border-radius: 40rpx;
  /* background: url(https://cmitoa.chinamobilesz.com:9110/static/img/courseBackground.png) 0 0 no-repeat;background-size: 100% 100%; */
}

/* 保存到手机 */

.saveBtn {
  display: block;
  width: 60%;
  height: 88rpx;
  padding: 0;
  line-height: 88rpx;
  text-align: center;
  position: fixed;
  bottom: 413rpx;
  left: 20%;
  background: #ff5b89;
  color: #fff;
  font-size: 30rpx;
  border-radius: 44rpx;
  z-index: 11;
}

/* 底部提醒 */

.remind {
  position: fixed;
  bottom: 330rpx;
  color: #ff5b89;
  font-size: 20rpx;
  z-index: 11;
  text-align: center;
  width: 100%;
}

/* 关闭按钮 */

.imagePathBox .close {
  display: block;
  width: 76rpx;
  height: 76rpx;
  position: fixed;
  bottom: 130rpx;
  left: 331rpx;
}

.imagePathBox .close image {
  width: 100%;
  height: 100%;
}