小程序canvas2d绘制页面并且生成图片在页面预览可下载转发

今天写了个canvas绘制图片生成图片支持长按转发下载,踩的坑有点多,记录一下!

整体思路为

  1. 绘制画布
  2. 将base64图片转存本地 
  3. 将图片绘制进画布
  4. 将canvas转换为本地url
  5. 将url转换为base64图片在页面预览
  6. 长按可下载或转发

附上效果图:

下载到本地的图
页面展现

 

index.wxml

<view class="container">
<image show-menu-by-longpress="1" class="qrCodeStr” src="{{tempFilePath}}"></image>
<canvas class="code" id="myQrcode" style="width: 100%;height:375px;margin: -2000px;'type="2d"canvas-id="myOrcode"/>
</view>

index.js

const app = getApp();
var util = require('../../../utils/util.js');
var QRCode = require('../../../utils/weapp_qrcode.js');
Page({

  /**
   * 页面的初始数据
   */
  data: {
    baseUrl: app.globalData.baseurl,
    qrCodeStr: null,
    title: '',
    tempFilePath: '',
    money: ''
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.setData({
      qrCodeStr: JSON.parse(decodeURIComponent(options.qrCodeStr)) || null,
      title: JSON.parse(decodeURIComponent(options.title)) || '',
      money: JSON.parse(decodeURIComponent(options.money)) || '',
    })
    let imgData = QRCode.drawImg(this.data.qrCodeStr, {
      typeNumber: 4, // 密度
      errorCorrectLevel: 'L', // 纠错等级
      size: 400, // 白色边框
    })
    this.setData({
      qrcodeImg: imgData
    })
    this.drewImages()
  },

  /**
   * 保存二维码
   */
  saveQrcode: function (e) {
    var that = this;
    wx.getSetting({
      success(res) {
        console.log(res);
        if (undefined == res.authSetting['scope.writePhotosAlbum']) {
          wx.authorize({
            scope: 'scope.writePhotosAlbum',
            success: function (res) {
              that.downloadAndSave();
            }
          })
        } else if (res.authSetting['scope.writePhotosAlbum']) {
          that.downloadAndSave();
        } else {
          utils.tips("请先授权可保存到相册");
          wx.openSetting();
        }
      }
    })

  },

  downloadAndSave: function () {
    var that = this;
    wx.showLoading({
      title: '保存中',
      mask: true
    });
    var url = this.data.qrcodeImg;
    console.log(url);
    wx.downloadFile({
      url: url,
      success: function (res) {
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success: function (res) {
            wx.hideLoading();
            utils.success("保存成功");
          },
          fail: function (err) {
            wx.hideLoading();
            console.log(err);
          }
        })
      },
      fail: function (err) {
        wx.hideLoading();
        console.log(err);
      }
    })
  },


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

  },

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

  },
  // canvas2D绘制画布
  drewImages: function () {
    var that = this
    const rpx = wx.getSystemInfoSync().windowWidth
    const dpr = wx.getSystemInfoSync().pixelRatio
    let xMargin = 10 / 750 * rpx //画布侧边距
    let yMargin = 20 / 750 * rpx //画布上下边距
    let lMargin = 10 / 750 * rpx + 2 //行距
    let textSize = parseInt(32 / 750 * rpx) //字体大小
    const textWidth = parseInt((398 / 750) * rpx); // 列表定宽,超出换行显示
    const secondLineHeight = parseInt((38 / 750) * rpx); // 一行超出,第二行多出的高度
    let imgWidth = parseInt(400 / 750 * rpx) //图片宽
    let imgHeight = parseInt(400 / 750 * rpx) //图片高
    let imgMarginTop = 100 / 750 * rpx + 2 //图片高
    var query = wx.createSelectorQuery()
    console.log(query)
    query.select("#myQrcode").fields({ node: true, size: true, }).exec(async (res) => {
      var canvas = res[0].node;
      var ctx = canvas.getContext("2d");
      canvas.width = res[0].width * dpr
      canvas.height = res[0].height * dpr
      ctx.scale(dpr, dpr)
      // 插入图片
      const fs = wx.getFileSystemManager();
      var times = new Date().getTime();
      var codeimg = wx.env.USER_DATA_PATH + '/' + times + '.png';
      let imgUrl = await new Promise((resolve, reject) => {
        //将base64图片写入
        fs.writeFile({
          filePath: codeimg,
          data: that.data.qrcodeImg.slice(22),
          encoding: 'base64',
          success: (red) => {
            resolve('')
          }, fail: function (e) {
            reject(e)
          }
        });
      });
      const canvasImg = canvas.createImage()
      canvasImg.src = codeimg
      let canvasImgPo = await new Promise((resolve, reject) => {
        canvasImg.onload = () => {
          resolve(canvasImg)
        }
        canvasImg.onerror = (e) => {
          reject(e)
        }
      });
      let imgCenter = (rpx / 2 - imgWidth / 2) - 15//图片居中显示
      ctx.drawImage(canvasImgPo, imgCenter, imgMarginTop, imgWidth, imgHeight);
      // 插入文字
      // 计算文字插入的高度
      let listHeight = yMargin + imgHeight + imgMarginTop + 30
      ctx.font = "16px Aril"
      ctx.fillText(that.data.title, imgCenter, listHeight)
      ctx.fillText('金额:', imgCenter, listHeight + 30)
      ctx.font = "16px Aril"
      ctx.fillStyle = "red"
      ctx.fillText('¥' + that.data.money, imgCenter + 43, listHeight + 30)
      wx.canvasToTempFilePath({
        canvas: canvas,
        success: (rev) => {
          that.getBase64(rev.tempFilePath)
        }
      })
    });
  },
  getBase64: function (url) {
    var that = this
    wx.getFileSystemManager().readFile({
      filePath: url,  //图片路径
      encoding: 'base64', //编码格式
      success: res => { //成功的回调
        that.setData({
          tempFilePath: 'data:image/png;base64,' + res.data.replace(/[\r\n]/g, '')
        })
      }
    })
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

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

  },

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

  },

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

  },

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

  }
})

注意:

1.base64图片不可直接绘制在画布中,需要下载到本地再使用drawImage方法,否则真机将无法显示

2.canvasToTempFilePath方法获取到的url不可直接用在页面中,需转为base64图片,否则真机将无法显示

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在小程序使用 Canvas2D 绘制页面生成图片,可以按照以下步骤进行: 1. 在 `wxml` 文件中添加 `canvas` 标签,设置宽高和 `canvas-id`。 ``` <canvas canvas-id="myCanvas" style="width: 100%; height: 100%;"></canvas> ``` 2. 在 `js` 文件中获取 `canvas` 上下文对象,并进行绘制绘制完成后可以通过 `canvasToTempFilePath` 方法将画布转换为临时图片路径。 ``` // 获取canvas上下文对象 const ctx = wx.createCanvasContext('myCanvas', this); // 绘制图形 ctx.setFillStyle('#ffffff'); ctx.fillRect(0, 0, 100, 100); ctx.setFillStyle('#000000'); ctx.setFontSize(20); ctx.fillText('Hello, World!', 10, 50); // 将画布转换为临时图片路径 ctx.draw(false, () => { wx.canvasToTempFilePath({ canvasId: 'myCanvas', success: (res) => { console.log(res.tempFilePath); }, fail: (res) => { console.log(res.errMsg); } }, this); }); ``` 3. 生成的临时图片路径可以通过 `Image` 组件显示在页面中。 ``` <image src="{{imageUrl}}" mode="aspectFill" style="width: 100%; height: 100%;"></image> ``` 完整代码示例: ``` // index.wxml <canvas canvas-id="myCanvas" style="width: 100%; height: 100%;"></canvas> <image src="{{imageUrl}}" mode="aspectFill" style="width: 100%; height: 100%;"></image> // index.js Page({ data: { imageUrl: '' }, onLoad() { const ctx = wx.createCanvasContext('myCanvas', this); ctx.setFillStyle('#ffffff'); ctx.fillRect(0, 0, 100, 100); ctx.setFillStyle('#000000'); ctx.setFontSize(20); ctx.fillText('Hello, World!', 10, 50); ctx.draw(false, () => { wx.canvasToTempFilePath({ canvasId: 'myCanvas', success: (res) => { this.setData({ imageUrl: res.tempFilePath }); }, fail: (res) => { console.log(res.errMsg); } }, this); }); } }); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值