小程序---将页面内容绘制成图片

本人大四实习新入职,在入职一个星期后接触到了第一个项目。
因为是新手,在整个开发过程中遇到了较多的难点:主要是canvas绘图过程中,因为商品图片和二维码来自于后台,绘制完成后发现只能在微信开发工具上显示,在真机(本人手机)上只能显示文本,图片为空白。多次测试后发现网络图片都无法在真机上绘制出来。
首先看下设计图,知道具体做的是什么样的:
这里写图片描述 ——–
——
具体就是在微信小程序商品详情页上添加一个分享按钮,点击按钮后将商品图片、描述、价格以及二维码绘制成一张图显示出来(项目中是详情页和首页两种图片)。利用微信小程序自带功能,长按可以将图片保存、分享、收藏、识别二维码。
接下来上代码,代码不齐全,主要是本人开发过程中用到的代码。(因为公司开发所用的是wepy小程序框架,所以代码写法上与原生小程序代码略有不同。需要的朋友请自行转行,重在理解这个过程。)
1.这个是wxml部分的代码。样式代码这里就不上了。

<view class="share" @tap="share">    
   分享
</view>   //点击分享按钮,调用事件“share”
<canvas canvas-id=’share’ style=’width:750px;height:920px;’ hidden={{canvasHidden}}’>
<canvas>

分享按钮点击的时候触发“share”方法,随后“share”方法里的getGoodEwm方式执行。
注意:
1.canvas-id 一定要设置,后面要用的上。
2.style里的宽高要用上,不设置宽高画板会失效。
3.canvasHidden是控制画板显示隐藏的参数,画板直接设置display none,会导致失效。

2.script部分。

Data{
//画布
   canvasHidden:true, //设置画板的显示与隐藏,画板不隐藏会影响页面正常显示
   shareImgPath: ''   //用于储存canvas生成的图片
}

自定义方法:

这里是getGoodEwm方法。需要注意的是因为二维码和商品图片都是后台获取的网络图片,所以一定要先获取二维码图片地址,在通过“wx.getImageInfo”方法获取图片信息,接着是商品图片的的信息获取(因为商品图片的api地址获取写在其他方法里,这里就不显示了,原理与二维码获取相同)只有在两张图片都获取到以后才能开始绘图,否则绘制不出图片。
注意代码后的注释

//二维码获取
 async getGoodEwm() {
    let that = this;
    let storeId = wepy.getStorageSync(STORE_ID) || {};
    let storeSkuSn = that.detail.storeSkuSn;
    const json = await api.getGoodEwm({
      query: {
            storeId : storeId,
            storeSkuSn : storeSkuSn         
      }
    });     //以上代码是后台获取二维码的方法,不是本问的重点。实际实验中可以把二维码图片地址用网络图片地址代替,也能实验效果
    console.log(json.data)
    if (json.data.code == 'success') { //这句表示如果二维码图片内容获取成功
        wx.showLoading({        //因为整个图片获取过程需要一定时间,所以添加一个提示框提醒用户
            title: '努力生成中...'
        })       
        wx.getImageInfo({       //获取二维码图片信息
            src: json.data.data,
            success:function(res){
                console.log("------------- succ -----------")
                console.log(res)
                wx.getImageInfo({    //二维码图片信息获取成功后,获取商品图片信息
                    src: that.detail.imgList[0],   //因为后台中商品图片有多张,数据是一个数组,所以这里只获取第一张。也可以用网络图片地址代替。
                    success:function(e){
                        console.log("------------- succ -----------")
                        console.log(e)
                        console.log(res)
                        that.drawImg(e,res)    //两张图片都获取成功后,调用绘图方法,注意传递过去的参数区别,不要混淆
                    },
                    fail:function(e){
                        console.log("------------- fail -----------")
                        console.log(e)
                    },
                    complete:function(e) {
                        console.log("------------- complete -----------")
                        console.log(e)
                    }
                });
            },
            fail:function(res){
                console.log("------------- fail -----------")
                console.log(res)
            },
            complete:function(res) {
                console.log("------------- complete -----------")
                console.log(res)
            }
        }); 
    } else {
        tip.error(json.data.errorMsg)
        console.log('失败')
    }
    that.$apply();
}
//绘图
   drawImg(e,res) {
      let that=this;
      that.canvasHidden=false  //设置画板显示,才能开始绘图

      var img=e.path       //商品图片保存地址
      var img1=res.path  //二维码图片保存地址   
      var name=this.detail.name  //图片描述,描述和下面的价格都是从后台获取的内容,可以随意换成其他文本内容,这里不是重点所以就不讲内容的获取方法了
      var price=this.detail.price     //图片价格
      let context = wx.createCanvasContext('share')  //这里的“share”是“canvas-id”

      context.setFillStyle('#fff')    //这里是绘制白底,让图片有白色的背景
      context.fillRect(0, 0, 750, 920)

      context.drawImage(img, 30, 30, 690, 690) //绘制商品图片

      context.setFontSize(28)
      context.setFillStyle("#393939")
      context.fillText(name, 30, 796)  //绘制描述

      context.setFontSize(32)
      context.setFillStyle("#f31115")
      context.fillText('¥'+price, 30, 870)   //绘制价格

      context.drawImage(img1, 576, 750, 144, 144) //绘制二维码图片

      //把画板内容绘制成图片,并回调画板图片路径
      context.draw(false, function () {
          wx.canvasToTempFilePath({
              x: 0,
              y: 0,
              width: 750,
              height: 920,
              destWidth: 750,
              destHeight: 920,
              canvasId: 'share',
              success:a=>{
                  that.shareImgPath=a.tempFilePath,   //将绘制的图片地址保存在shareImgPath 中
                  that.canvasHidden=true           //设置画板隐藏,否则影响界面显示
                  that.$apply();             //更改data的值 等同于小程序原生代码的setData
                  console.log(that.data.shareImgPath)    
                  wx.previewImage({     //将图片预览出来
                      urls: [that.data.shareImgPath]
                  })
                  wx.hideLoading()  //图片已经绘制出来,隐藏提示框
              },
              fail:e=>{console.log('失败')}
          })
      })                       
   }
Methods={
//分享事件
  share() {
    this.getGoodEwm();                   
  }
}

解释下代码:
分享按钮点击的时候触发“share”方法,随后“share”方法里的getGoodEwm方式执行。需要注意的是因为二维码和商品图片都是后台获取的网络图片,所以一定要先获取二维码图片地址,在通过“wx.getImageInfo”方法获取图片信息,接着是商品图片的的信息获取(因为商品图片的api地址获取写在其他方法里,这里就不显示了,原理与二维码获取相同)只有在两张图片都获取到以后才能开始绘图,否则绘制不出图片。
Canvas绘图的方法可以去看小程序官方文档,对着代码看一次就能够理解了。图片绘制出来后将地址保存在data的“shareImgPath”中,之后调用“wx.previewImage”方法将图片预览出来。长按图片就会自动调用微信小程序原生功能:保存、收藏等。
其实整个项目的重点在于怎么把网络图片绘制出来,如果是本地图片的话其实会少很多步骤,但是网络图片就一定要先采用wx.getImageInfo()方法将图片保存下来,在调用绘制。项目中因为图片是后台获取的,所以多了调用api获取后台图片。

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在小程序中使用 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); }); } }); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值