小程序截图保存到相册 绘图(使用painter)

微信小程序,截屏截图,都需要重新绘制画布,生成图片.
简单的静态布局,可以直接使用canvas.
然而,大量动态数据, 动态布局, 使用canvas,实现起来就有些过于繁琐了.在实现对界面截图的过程中, 使用到了painter组件.接下来介绍一下功能实现过程中painter的使用.

.json文件

{
  "navigationBarTitleText": "图片名片",
  "backgroundColor": "#f5f5f5",
  "usingComponents": {
    "painter": "/pages/components/painter/painter"
  }
}

.wxml文件

palette: 是绘制属性,赋值后, 画布绘制保存到本地,就是按照此属性的赋值数据来的.
dancePalette: 是展示在现存界面里的布局;
在实现截图功能时, 还是觉得 wxml的布局效率比较精准, 比较高, 所以展示给用户的, 是用wxml实现的布局.并没有给dancePalette赋值,当然在调试的时候 也是可以给dancePalette直接赋和palette一样的值, 来查看绘制效果的, 具体用不用,看个人习惯和项目需求;

<painter
palette="{{template}}"
bind:imgOK="onImgOK" 
/>

.wxss文件

painter{width: 100%;height: 1264rpx;}

.js文件(核心绘制代码)
注:

*绘制代码看似比较繁琐, 其实有辅助工具的哟painter-custom-poster,
可以先利用painter-custom-poster生成大概布局数据,再进行微调, 很方便*

painter-custom-poster地址

为了 方便动态赋值实现动态布局,我直接在.js文件里处理了布局数据. 如果界面相对简单, 可以独立出来一个.js 文件,导入本界面index.js文件中.

//这里额外创建了一个.js文件,将一些静态布局数据分离了出去. 所以需要做一下导入
import Card from './draw/getpic.js';
  onShow: function() {
    this.getWritePhotos();//获取微信授权保存相册
  },
//此函数就是简单的界面数据请求,不做赘述.将drawPic函数在此调用确保绘制图片的时候,数据已经拿到
getCardDetail: function(cardId) {
app.$ajax({
      url: '本页面数据网络请求接口',
      data: {
      入参名:入参
      },
      contentType: "application/json",
      method: "GET"
    }).then(res => {
        that.drawPic();
    });
}

// 绘制
  drawPic: function() {
//这里额外创建了一个.js文件,将一些静态布局数据分离了出去. 
    let card = new Card().palette();
    this.setData({
      template: card,
    });
    //绘制动态数据
    this.manageCardPainterPhoto();
  },
    //绘制动态数据
manageCardPainterPhoto: function() {
    let that = this;
    let card = this.data.template;
    // 用户信息
    card.views.push({
      "type": "image",
      "url": `${that.data.cardInfo.headImg}`,
      "css": {
        "width": "160rpx",
        "height": "160rpx",
        "top": "88rpx",
        "left": "300rpx",
        "rotate": "0",
        "borderRadius": "80rpx",
        "borderWidth": "1rpx",
        "borderColor": "#fff",
        "shadow": "",
        "mode": "scaleToFill"
      }
    }, {
      "type": "text",
      "text": `${that.data.cardInfo.userName}`,
      "css": {
        "color": "#fff",
        "background": "rgba(0,0,0,0)",
        "width": "690rpx",
        "height": "118rpx",
        "top": "264rpx",
        "left": "30rpx",
        "rotate": "0",
        "borderRadius": "",
        "borderWidth": "",
        "borderColor": "#000000",
        "shadow": "",
        "padding": "0px",
        "fontSize": "44rpx",
        "fontWeight": "bold",
        "maxLines": "1",
        "lineHeight": "62rpx",
        "textStyle": "fill",
        "textDecoration": "none",
        "fontFamily": "",
        "textAlign": "center"
      }
    }, {
      "type": "text",
      "text": `${that.data.cardInfo.companyName}`,
      "css": {
        "color": "#fff",
        "background": "rgba(0,0,0,0)",
        "width": "690rpx",
        "height": "37rpx",
        "top": "376rpx",
        "left": "30rpx",
        "rotate": "0",
        "borderRadius": "",
        "borderWidth": "",
        "borderColor": "#000000",
        "shadow": "",
        "padding": "0px",
        "fontSize": "26rpx",
        "fontWeight": "normal",
        "maxLines": "1",
        "lineHeight": "37rpx",
        "textStyle": "fill",
        "textDecoration": "none",
        "fontFamily": "",
        "textAlign": "center"
      }
    }, {
      "type": "text",
      "text": `${that.data.cardInfo.phone}`,
      "css": {
        "color": "#fff",
        "background": "rgba(0,0,0,0)",
        "width": "690rpx",
        "height": "37rpx",
        "top": "410rpx",
        "left": "30rpx",
        "rotate": "0",
        "borderRadius": "",
        "borderWidth": "",
        "borderColor": "#000000",
        "shadow": "",
        "padding": "0px",
        "fontSize": "26rpx",
        "fontWeight": "normal",
        "maxLines": "1",
        "lineHeight": "37rpx",
        "textStyle": "fill",
        "textDecoration": "none",
        "fontFamily": "",
        "textAlign": "center"
      }
    });

    //用户身份
    if (that.data.identityList.length > 0) {
      let identityCount = that.data.identityList.length;
      let margin_L = (750 - 84 - (84 + 24) * (identityCount - 1)) / 2;
      for (let i = 0; i < that.data.identityList.length; i++) {
        card.views.push({
          "type": "text",
          "text": `${that.data.identityList[i]}`,
          "css": {
            "color": "#fff",
            "background": "rgba(255,255,255,0.1)",
            "width": "84rpx",
            "height": "28rpx",
            "top": "332rpx",
            "left": `${margin_L + i * (84 + 24)}rpx`,
            "rotate": "0",
            "borderRadius": "14rpx",
            "borderWidth": "",
            "borderColor": "#000000",
            "shadow": "",
            "padding": "0px",
            "fontSize": "20rpx",
            "fontWeight": "normal",
            "maxLines": "1",
            "lineHeight": "28rpx",
            "textStyle": "fill",
            "textDecoration": "none",
            "fontFamily": "",
            "textAlign": "center"
          }
        });
      }
    }
    // let views = card.views;
    // let brand_top = 528;
    let shop_top = 528;
    // //品牌
    if (this.data.brandList.length > 0) {
      card.views.push({
        "type": "text",
        "text": `品牌${that.data.brandNum}个`,
        "css": {
          "color": "#000000",
          "background": "rgba(0,0,0,0)",
          "width": "230rpx",
          "height": "31rpx",
          "top": "528rpx",
          "left": "260rpx",
          "rotate": "0",
          "borderRadius": "",
          "borderWidth": "",
          "borderColor": "#000000",
          "shadow": "",
          "padding": "0px",
          "fontSize": "28rpx",
          "fontWeight": "bold",
          "maxLines": "1",
          "lineHeight": "30rpx",
          "textStyle": "fill",
          "textDecoration": "none",
          "fontFamily": "",
          "textAlign": "center"
        }
      });
      for (let i = 0; i < that.data.brandList.length; i++) {
        if (i === 3) {
          card.views.push({
            "type": "rect",
            "css": {
              "background": "#fff",
              "width": "144rpx",
              "height": "144rpx",
              "top": "592rpx",
              "left": `${62 + i * (144 + 16)}rpx`,
              "rotate": "0",
              "borderRadius": "0",
              "borderWidth": "1rpx",
              "borderColor": "#e5e5e5",
              "shadow": "",
              "color": "#fff"
            }
          }, {
            "type": "text",
            "text": "···",
            "css": {
              "color": "#333",
              "background": "#fff",
              "width": "144rpx",
              "height": "34rpx",
              "top": "648rpx",
              "left": `${62 + i * (144 + 16)}rpx`,
              "rotate": "0",
              "borderRadius": "",
              "borderWidth": "",
              "borderColor": "#000000",
              "shadow": "",
              "padding": "0px",
              "fontSize": "24rpx",
              "fontWeight": "normal",
              "maxLines": "1",
              "lineHeight": "34rpx",
              "textStyle": "fill",
              "textDecoration": "none",
              "fontFamily": "",
              "textAlign": "center"
            }
          })
        } else {
          let model = that.data.brandList[i];
          let brandName = that.appendBrandName([model.brandName, model.brandNameEn, model.brandNameOther]);
          card.views.push({
            "type": "rect",
            "css": {
              "background": "#fff",
              "width": "144rpx",
              "height": "144rpx",
              "top": "592rpx",
              "left": `${62 + i*(144+16)}rpx`,
              "rotate": "0",
              "borderRadius": "0",
              "borderWidth": "1rpx",
              "borderColor": "#e5e5e5",
              "shadow": "",
              "color": "#fff"
            }
          }, {
            "type": "image",
            "url": `${model.brandLogo}`,
            "css": {
              "width": "112rpx",
              "height": "112rpx",
              "top": "593rpx",
              "left": `${78 + i * (144 + 16)}rpx`,
              "rotate": "0",
              "borderRadius": "0",
              "borderWidth": "1rpx",
              "borderColor": "#fff",
              "shadow": "",
              "mode": "scaleToFill"
            }
          }, {
            "type": "text",
            "text": `${brandName}`,
            "css": {
              "color": "#333",
              "background": "rgba(0,0,0,0)",
              "width": "144rpx",
              "height": "27rpx",
              "top": "704rpx",
              "left": `${62 + i * (144 + 16)}rpx`,
              "rotate": "0",
              "borderRadius": "",
              "borderWidth": "",
              "borderColor": "#000000",
              "shadow": "",
              "padding": "0px",
              "fontSize": "24rpx",
              "fontWeight": "normal",
              "maxLines": "1",
              "lineHeight": "27rpx",
              "textStyle": "fill",
              "textDecoration": "none",
              "fontFamily": "",
              "textAlign": "center"
            }
          });
        }
      }
      shop_top = 776;
      that.setData({
        template: card
      })
    }
    //店铺
    if (this.data.shopList.length > 0) {
      card.views.push({
        "type": "text",
        "text": `店铺${that.data.shopNum}个`,
        "css": {
          "color": "#000000",
          "background": "rgba(0,0,0,0)",
          "width": "230rpx",
          "height": "31rpx",
          "top": `${shop_top}rpx`,
          "left": "260rpx",
          "rotate": "0",
          "borderRadius": "",
          "borderWidth": "",
          "borderColor": "#000000",
          "shadow": "",
          "padding": "0px",
          "fontSize": "28rpx",
          "fontWeight": "bold",
          "maxLines": "1",
          "lineHeight": "30rpx",
          "textStyle": "fill",
          "textDecoration": "none",
          "fontFamily": "",
          "textAlign": "center"
        }
      });
      for (let i = 0; i < that.data.shopList.length; i++) {
        if (i === 3) {
          card.views.push({
            "type": "rect",
            "css": {
              "background": "#fff",
              "width": "304rpx",
              "height": "112rpx",
              "top": `${shop_top + 64 + parseInt(i / 2) * 128}rpx`,
              "left": `${62 + i % 2 * 320}rpx`,
              "rotate": "0",
              "borderRadius": "12rpx",
              "borderWidth": "1rpx",
              "borderColor": "#e5e5e5",
              "shadow": "",
              "color": "#fff"
            }
          }, {
            "type": "text",
            "text": "···",
            "css": {
              "color": "#333",
              "background": "#fff",
              "width": "304rpx",
              "height": "34rpx",
              "top": `${shop_top + 64 + parseInt(i / 2) * 128 + 39}rpx`,
              "left": "382rpx",
              "rotate": "0",
              "borderRadius": "",
              "borderWidth": "",
              "borderColor": "#000000",
              "shadow": "",
              "padding": "0px",
              "fontSize": "24rpx",
              "fontWeight": "bold",
              "maxLines": "1",
              "lineHeight": "34rpx",
              "textStyle": "fill",
              "textDecoration": "none",
              "fontFamily": "",
              "textAlign": "center"
            }
          })

        } else {
          let model = that.data.shopList[i];
          let level_img = "/images/shoplevelicons/shoplevel_" + model.shopLevel + ".png";
          card.views.push({
            "type": "rect",
            "css": {
              "background": "#fff",
              "width": "304rpx",
              "height": "112rpx",
              "top": `${shop_top + 64 + parseInt(i / 2) * 128}rpx`,
              "left": `${62 + i % 2 * 320}rpx`,
              "rotate": "0",
              "borderRadius": "14rpx",
              "borderWidth": "1rpx",
              "borderColor": "#e5e5e5",
              "shadow": "",
              "color": "#fff"
            }
          }, {
            "type": "rect",
            "css": {
              "background": "#fff",
              "width": "80rpx",
              "height": "80rpx",
              "top": `${shop_top + 64 + parseInt(i / 2) * 128 + 16}rpx`,
              "left": `${62 + i % 2 * 320 + 16}rpx`,
              "rotate": "0",
              "borderRadius": "42rpx",
              "borderWidth": "1rpx",
              "borderColor": "#e5e5e5",
              "shadow": "",
              "color": "#f8f8f8"
            }
          }, {
            "type": "image",
            "url": `${model.shopImg}`,
            "css": {
              "width": "80rpx",
              "height": "80rpx",
              "top": `${shop_top + 64 + parseInt(i / 2) * 128 + 16}rpx`,
              "left": `${62 + i % 2 * 320 + 16}rpx`,
              "rotate": "0",
              "borderRadius": "42rpx",
              "borderWidth": "1rpx",
              "borderColor": "#fff",
              "shadow": "",
              "mode": "scaleToFill"
            }
          }, {
            "type": "text",
            "text": `${model.shopName}`,
            "css": {
              "color": "#333",
              "background": "rgba(0,0,0,0)",
              "width": "180rpx",
              "height": "31rpx",
              "top": `${shop_top + 64 + parseInt(i / 2) * 128 + 16}rpx`,
              "left": `${62 + i % 2 * 320 + 112}rpx`,
              "rotate": "0",
              "borderRadius": "",
              "borderWidth": "",
              "borderColor": "#000000",
              "shadow": "",
              "padding": "0px",
              "fontSize": "28rpx",
              "fontWeight": "bold",
              "maxLines": "1",
              "lineHeight": "30rpx",
              "textStyle": "fill",
              "textDecoration": "none",
              "fontFamily": "",
              "textAlign": "left"
            }
          }, {
            "type": "image",
            "url": `${level_img}`,
            "css": {
              "width": "auto",
              "height": "24rpx",
              "top": `${shop_top + 64 + parseInt(i / 2) * 128 + 64}rpx`,
              "left": `${62 + i % 2 * 320 + 112}rpx`,
              "rotate": "0",
              "borderRadius": "0",
              "borderWidth": "1rpx",
              "borderColor": "#fff",
              "shadow": "",
              "mode": "auto"
            }
          });
        }
      }
    }
    // 底部二维码
    card.views.push({
      "type": "image",
      "url": `${that.data.qrCodeUrl}`,
      "css": {
        "width": "180rpx",
        "height": "180rpx",
        "top": "1100rpx",
        "left": "516rpx",
        "rotate": "0",
        "borderRadius": "",
        "borderWidth": "1rpx",
        "borderColor": "#fff",
        "shadow": "",
        "mode": "scaleToFill"
      }
    });
    that.setData({
      template: card
    })
  },
  onImgErr(e) {
    wx.hideLoading()
    wx.showToast({
      title: '生成分享图失败,请刷新页面重试'
    })
  },
//生成图片成功后会触发的函数
  onImgOK(e) {
    wx.hideLoading()
    this.setData({
      sharePath: e.detail.path,
      visible: true,
    })
  },
// 打开授权设置页面
  openSetting: function() {
    wx.openSetting();
    this.setData({
      showAuthDialog: false
    });
  },
  //获取微信授权保存相册
  getWritePhotos: function() {
    let that = this;
    wx.getSetting({
      success(res) {
        if (!res.authSetting['scope.writePhotosAlbum']) {
          wx.authorize({
            scope: 'scope.writePhotosAlbum',
            success() {
              that.setData({
                writePhotosAlbum: true
              });
            },
            fail() {
              that.setData({
                writePhotosAlbum: false
              });
            }
          });
        } else {
          that.setData({
            writePhotosAlbum: true
          });
        }
      }
    });
  },

界面wxml布局效果图---> 保存到相册的画布效果图


截屏2020-05-14下午4.09.29.png
截屏2020-05-14下午4.10.31.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339