微信小程序中把页面生成图片

这个问题我上网搜了一下,答案有多种,但是真正能用的没有几何。很多答案都是雷同,有的网友也不负责任,直接拿来照抄,自己也不跑一遍看看。哎,不说了,说多了全是泪。希望我们的技术达人在分享的时候,能够真实的走一遍代码,尽量能让我等小白看的懂啊。闹骚发过了,下面我们就进入正题吧(*^__^*) 嘻嘻……

今天分享的是不仅仅把页面生成图片,同时,也要满足能够识别图中的二维码。我们先来看看效果图。点击生成海报,就生成右侧图片

其中左边的图片是页面,右边是生成的图片。具体实现代码如下:

一、页面布局(wxml)

<view class="am_box">
 <view class="am_hysn">好友送您</view>
 <view class="am_jyq">15元加油券</view>

 <!--福利开始-->
  <view class="am_fuli">
    <view class="am_bk">
      <view class="am_title">用悦孚加油  享四大福利</view>
    <view class="am_fltype">
      <view class="am_type">每次加油都省钱</view>
      <view class="am_type">实时查价更便捷</view>
      <view class="am_type">油品保障资质全</view>
      <view class="am_type">悦孚油站任你选</view>
    </view>
    </view>
   
  </view>
 <!--福利结束-->

 <view class="am_result" style="{{'padding-left:' + winWidth}}">
    <canvas class="canvas-poster" id="mycanvas" canvas-id="mycanvas"></canvas>
  </view>
  <view class="am_sub_title">油好  省钱  去悦孚</view>
   <view class='am_Mselect'>
        <button open-type="share" id="btn"  size="mini">
            <image src="/images/share01@2x.png'" mode="aspectFill" class="am_wx"></image>
          <text class="am_wxhy">微信好友</text>
          </button>

        <view class="am_share" catchtap="clickSaveImg">
          <image src="/images/savepic.png" mode="aspectFill" class="am_wx"></image>
          <text class="am_wxhy">生成海报</text>
        </view>
    </view> 
</view>

<!--分享开始-->
<view class="sign_success_popup"  wx:if="{{canvasType}}">
  <view class="popup_mask"></view>
  <view class="popup_content">
  <canvas class='canvas' canvas-id="hbmycanvas" id="hbmycanvas"  />
  <view class="bottom-dialog-body">
    <view class='Mcancel' bindtap='mCancel'><text>取消</text></view>
    <view class="am_save" catchtap="saveImg">保存到本地相册</view>
  </view>
</view>
</view>
  <!--分享介绍-->

二、页面样式(wxss)

.am_box {
  width:100%;
  height: 100%;
  position: fixed;
  top:0;
  box-sizing: border-box;
  padding:170rpx 40rpx 10rpx 40rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  background:url('背景图片') no-repeat;
  background-size: 100% 100%;
  overflow: hidden;
}

.am_hysn {
  color:#ffffff;
  font-family: 'FZY3B';
  font-size: 104rpx;
}

.am_jyq {
  color:#ffffff;
  font-family: 'FZY3B';
  font-weight: bold;
  font-size: 120rpx;
  line-height: 136rpx;
text-shadow: 2rpx 3rpx 0rpx #FFAC3E;
}
.am_img {
  width:100%;
  margin:0 auto;
  text-align: center;
  box-sizing: border-box;
}
.am_img > image {
  width:100%;
  height:505px;
}
.canvas {
  width: 100%;
  height: -webkit-calc(100% - 44px);
  height: -moz-calc(100% - 44px);
  height: calc(100% - 44px);
}
.am_Mselect{
  width:100%;
 background:#ffffff;
 display: flex;
 justify-content: space-around;
 align-items: center;
 border-radius: 10rpx;
}
.am_wxhy {
  color:#323232;
  font-size:28rpx;
  font-weight: 550;
}
.am_wx {
  width:80rpx;
  height:80rpx;
}

#btn {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* padding:25rpx;*/
  background:#ffffff; 
}
.am_share {
  width:50%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding:25rpx;
}
.bottom-positon{-webkit-transform:translateY(100%);transform:translateY(100%);}
.modal{position:fixed; top:0; right:0; bottom:0; left:0; z-index:1000;}
.modal-cancel{position:absolute; z-index:2000; top:0; right:0; bottom: 0; left:0; background:rgba(0,0,0,0.3);}
.bottom-dialog-body{
  width:100%;
  box-sizing:border-box;
  display:flex;
  justify-content: space-around;
  align-items: center;
  margin-top:-5rpx;
}

.Mcancel{
  width:50%;
  text-align: center;
  background: #fff;
  line-height: 80rpx;
  height: 80rpx;
  color:#333333;
 }
 
 /**弹窗开始**/
 .sign_success_popup {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
  width: 100vw;
  height: 100vh;
}

.popup_mask {
  position: absolute;
  width: 100%;
  height: 100%;
  z-index: -1;
  background: rgba(0, 0, 0, .33);
}

.am_save {
  width:50%;
  box-sizing: border-box;
  background:#19BE6B;
  color:#FFFFFF;
  text-align: center;
  line-height: 80rpx;
  height: 80rpx;
}

.popup_content {
  position: relative;
  width: 90%;
  height: 90%;
  margin: 7vh auto;
  padding: 20rpx 16rpx 0;
  text-align: center;
  outline:none;
  background:transparent;
}

/**弹窗结束**/

/**福利开始**/
.am_fuli {
  width:100%;
  box-sizing: border-box;
  background: #FFFFFF;
 border-radius: 20rpx;
 margin-top:50rpx;
}

.am_bk {
  width:100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  background:url('背景图片') no-repeat;
  background-size: 100% 100%;
  padding:50rpx 25rpx 50rpx 25rpx;
}

.am_title {
  font-size: 40rpx;
  font-family: 'FZY3JW','FZY3B';
  font-weight: 400;
  color: #FF4200;
  margin-bottom:50rpx;
}

.am_fltype {
  width:100%;
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
}

.am_type {
  width:48%;
  box-sizing: border-box;
  text-align: center;
  height: 86rpx;
  line-height: 86rpx;
background: linear-gradient(180deg, #FDF0C4, #FDBE7A);
border-radius: 13rpx;
color:#6E3F1A;
font-size: 28rpx;
margin-bottom:25rpx;
}
/**福利结束**/

.am_result {
   width: 240rpx;
  height: 240rpx;
  /* background: #FFFFFF;
  border: 2px solid #9FCA4C;
  border-radius: 25rpx;
  box-sizing: border-box;  */
  margin-top:30rpx;
  text-align: center;
  padding-left:20rpx;
}

.canvas-poster {
  height:200rpx;
 }

 .am_sub_title {
   width:100%;
   box-sizing: border-box;
   text-align: center;
  font-size: 32rpx;
  font-family: FZZhunYuan-M02;
  font-weight: 400;
  color: #FFFFFF;
  line-height: 45rpx;
  text-shadow: 1rpx 1rpx 0rpx #393939;
  margin-top:0rpx;
  margin-bottom:20rpx;
 }

三、页面JS处理(js)

const app = getApp();
const util = require('../../../utils/util.js');
const moment = require('../../../utils/moment.js'); //时间处理,可以从网上下载
const baseUrl = getApp().globalData.baseUrl;
const qrcode = require('../../../utils/weapp.qrcode'); //生成二维码,可以从网上下载
Page({

  /**
   * 页面的初始数据
   */
  data: {
    title:'邀请好友得加油券',
    money:15,
    imgUrl:getApp().globalData.imgUrl,
    _width: 0, //手机屏宽
    _heigth: 0,//手机屏高
    swiperHeight: 300,//主图图片高度
    canvasType: false,//canvas是否显示
    loadImagePath: '',//下载的图片
    imageUrl: 'https://www.xx.com/uploadPath/miniapppic/fx_bg002.png', //主图网络路径
    picUrl: 'https://www.xx.com/uploadPath/miniapppic/fx_pic0.png',//福利网络图片
    codeUrl: '',//二维码网络路径
    localImageUrl: '', //主图本地路径
    localCodeUrl: '', //绘制的二维码图片本地路径
    localPicUrl:'', //绘制福利图片本地路径
    animationData: {},
    tel:'',
    winWidth:'',
  },

  /**
  * 生成二维码带LOGO
  */
 formSubmit(mobile) {
  if (mobile) {
   var that = this;
   wx.showToast({
     title: '二维码生成中...',
     icon: 'loading',
     duration: 1000
   });
   qrcode({
    width:100,
    height:100,
    canvasId:'mycanvas',
     text:'https://www.xxx.com/inviteRegister?mobile=' + mobile,
     image:{
      imageResource:'../../../images/am_logo.png', //logo图片
      dx: 35,
      dy: 35,
      dWidth: 30,
      dHeight: 30
     },
     cbResult: function(res) {
         console.log('回调:',res)
      }
   });
   setTimeout(function () {
     wx.hideToast()
     wx.canvasToTempFilePath({
      canvasId: 'mycanvas',
      success: function (res) {
        console.log('临时二维码地址:',res)
        var codeUrl = res.tempFilePath;
        that.setData({
          codeUrl: codeUrl,
        });
      },
      fail: function (res) {
        console.log(res);
      }
    });
   }, 1000);
  }
},


  /**
   * 关闭弹窗
   */
  mCancel() {
    this.setData({
      canvasType:false,
    });
  },

//生成海报
  clickSaveImg() {
    let that = this
    // 获取屏幕宽高
    wx.showLoading({
      title: '正在生成海报',
    })
    /*获取手机宽高*/
    let imgHeigth = this.data.swiperHeight
    let imgUrl = this.data.imageUrl
    let qrcodeUrl = this.data.codeUrl
    wx.getSystemInfo({
      success(res) {
        that.setData({
          _width: res.windowWidth,
          _heigth: res.windowHeight,
          canvasType: true,
        })
        // 获取图片信息生成canvas
        that.getImginfo([imgUrl, qrcodeUrl], 0);
      }
    })
  },

  //把福利图片变成本地图片
  getPicImgInfo() {
    let that = this;
    wx.getImageInfo({
      src: that.data.picUrl,
      success:function(res) {
        console.log('把福利图片变成本地图片',res)
        that.setData({
          localPicUrl:res.path,
        });
      },
      fail:function(err) {
        console.log('把福利图片变成本地图片失败了:', err) 
      }
    })
  },

// 获取图片信息
getImginfo(urlArr, _type) {
  let that = this;
    wx.getImageInfo({
      src: urlArr[_type], 
      success: function (res) {
        console.log('是网络图片的本地地址',res)
        //res.path是网络图片的本地地址
        if (_type === 0) { //背景图片
          that.setData({
            localImageUrl: res.path,
          })
          that.getImginfo(urlArr, 1)
        } else {
          that.setData({ //二维码
            localCodeUrl: res.path,
          })
          // 创建canvas图片
          that.createNewImg();
        }
      },
      fail: function (res) {
        //失败回调
        console.log('Fail:', _type, res)
      }
    });
},

//绘制canvas
createNewImg: function () {
  let _width = this.data._width,
    _heigth = this.data._heigth; //屏幕宽与高

  let imgHeigth = this.data.swiperHeight, //原图片高度
    scale = (_width - 40) / _width, //缩小比例
    that = this;
  let imgH = imgHeigth * scale; //绘制时图片显示高度  
  let ctx = wx.createCanvasContext('hbmycanvas');

  //绘制图片
  ctx.drawImage(that.data.localImageUrl, 0, 0, util.rpxToPx(685), util.rpxToPx(1285));

  // 绘制标题
  ctx.setFontSize(35);
  ctx.setFillStyle('#ffffff');
  ctx.fillText('好友送您', util.rpxToPx(190), 80, imgH + 40, txtWidth);
  let txtWidth = _width - 60 + 30 - 100 - 50; //文字的宽度
  let bigTitle = that.data.money + '元加油券';
  // 绘制大标题
  ctx.setFontSize(50);
  ctx.setFillStyle('#ffffff');
   ctx.fillText(bigTitle, util.rpxToPx(90), 150, imgH + 65, txtWidth);
  //绘制福利图片
  ctx.drawImage(that.data.localPicUrl, util.rpxToPx(60),util.rpxToPx(350), util.rpxToPx(505), 220);
  // 绘制二维码
  ctx.drawImage(this.data.localCodeUrl, util.rpxToPx(210),  util.rpxToPx(800), 300, 100);

  // 绘制小程序名称
  ctx.setFontSize(15);
  ctx.setFillStyle('#ffffff');
  ctx.fillText('油好  省钱  去悦孚',  util.rpxToPx(190), util.rpxToPx(1030), imgH + 105, txtWidth);
  

  // 显示绘制
  ctx.draw();

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

//保存图片
saveImg() {
  let that = this
  wx.getSetting({
    success(res) {
      if (res.authSetting['scope.writePhotosAlbum']) {
         // 用户已经授权
         that.saveImage();
      } else {
        //未授权
        wx.authorize({
          scope: 'scope.writePhotosAlbum',
          success() {
            that.saveImage();
          },
          fail(err) {
            if (err && err.errMsg.endsWith("auth deny")) {
              wx.showModal({
                title: '授权添加到相册',
                content: '需要获取您的添加相册权限,请确认授权,否则分享功能无法正常使用',
                success: function (resolve) {  
                  if (resolve.confirm) { // 用户同意设置授权
                    wx.openSetting({
                      success(res) {
                        if (res && res.authSetting['scope.writePhotosAlbum']) {
                          that.saveImage(); // 执行保存函数
                        }
                      },
                      fail(res) {   // 用户拒绝设置授权
                        console.log(res)
                        wx.showToast({
                          title: '没有权限,保存失败',
                          icon:'none'
                        })
                      }
                    })
                  } else {  // 用户拒绝设置
                    wx.showToast({
                      title: '没有权限,保存失败',
                      icon:'none'
                    })
                  }
                }
              })
            } else {
              wx.showModal({
                  title: '提示',
                  content: '获取权限失败,将无法保存到相册哦~',
                  showCancel: false,
              })
            }
          },
        });
      }
    },
  });
},


saveImage() {
  let that = this;
  //不知道是什么原因,手机环境能正常显示
  wx.saveImageToPhotosAlbum({  //保存图片到相册
    filePath: that.data.loadImagePath, //生成图片临时路径
    success: function () {
        wx.showToast({
            title: "图片已保存至相册!",
            duration: 2000
        })
    }
})
},



  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    let userInfo =  wx.getStorageSync('userInfo');
    let that = this;
    console.log('用户:',userInfo)
    if (userInfo) {
       this.formSubmit(userInfo.mobile); //生成二维码
       this.getPicImgInfo(); 
       this.setData({
         tel:userInfo.mobile
       });
    }  else {
      util.isLogin(); //登录判断
    }

    wx.getSystemInfo({
      success (res) {
        console.log('屏幕宽度',res)
        that.setData({
          winWidth:res.windowWidth/7 + 'rpx'
        });
      }
    })
  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {
    return {
      title: this.data.title||'邀请好友得加油券',
      path: "/pages/xx/xx?mobile=" + this.data.tel + '&lx=1&id=klk',
      success: function (res) {

      },
      };
  }
})

四、utils相关函数

//utils相关函数

/**
 * 判断用户是否登录
 */
 function isLogin() {
	wx.showModal({
	title:'提示',
  content:'请先登录,然后进行后续操作!',
  showCancel: false, 
	success:function(res) {
		if (res.confirm) {
				wx.reLaunch({
					url:'/pages/index/index'
				})
		}
	}
	})
}

//尺寸转换
function rpxToPx(data = 0) {
  return ((data * wx.getSystemInfoSync().windowWidth)) / 700
}

module.exports = {
isLogin,
rpxToPx
}

以上就是微信小程序生成海报的过程,本人亲测有效。里面涉及到的图片地址自己替换

评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值