微信小程序生成分享海报

164 阅读1分钟
  1. 项目导入Painter
git clone https://github.com/Kujiale-Mobile/Painter.git
  1. 在pages.json的globalStyle中引入自定义组件,注意目录为第一步引入的代码所在目录
"usingComponents":{
  "painter":"/components/painter/painter"
}
  1. 在项目static文件夹建立base64.js(图片解码用)和sol-poster.js(画板配置所需参数)
// base64.js 

const fsm = wx.getFileSystemManager();
const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名

function base64src(base64data, cb) {
  const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
  if (!format) {
    return (new Error('ERROR_BASE64SRC_PARSE'));
  }
  const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
  const buffer = wx.base64ToArrayBuffer(bodyData);
  fsm.writeFile({
    filePath,
    data: buffer,
    encoding: 'binary',
    success() {
      cb(filePath);
    },
    fail() {
      console.log(res);
      return (new Error('ERROR_BASE64SRC_WRITE'));
    },
  });
};

export { base64src };


// sol-poster.js

export default class ImageExample {
  palette(params) {
	  //console.log(params)
    return ({
      width: '560rpx',
      height: '830rpx',
      background: '#fff',
      views: [
        {
          type: 'text',
          text: `${params.title}`,
          css: {
            left: '40rpx',
            top: '30rpx',
            fontSize: '30rpx',
            maxLines: '2',
            width: '480rpx',
            lineHeight: '40rpx',
        	color:'#ff7500'
          },
        },
		{
          type: 'text',
          text: `${params.desc}`,
          css: {
            left: '40rpx',
            top: '125rpx',
            fontSize: '24rpx',
            maxLines: '3',
            width: '480rpx',
            lineHeight: '40rpx',
			color:'#f00'
          },
        },
        {
          type: 'image',
          url: `${params.img2}`,
          css: {
            width: '480rpx',
            height: '480rpx',
            top: '170rpx',
            left: '40rpx',
            borderRadius:'5px'
          },
        },
        {
          type: 'image',
          url: `${params.img3}`,
          css: {
            width: '120rpx',
            height: '120rpx',
            right: '50rpx',
            bottom: '30rpx',
          },
        },
       {
         type: 'text',
         text: `自定义文字....`,
         css: {
           left: '40rpx',
           bottom: '90rpx',
           fontSize: '26rpx',
           maxLines: '2',
           width: '250rpx',
           lineHeight: '36rpx',
           color:'#858585'
         },
       },
	   {
	     type: 'text',
	     text: `长按识别小程序码下单!`,
	     css: {
	       left: '40rpx',
	       bottom: '30rpx',
	       fontSize: '20rpx',
	       maxLines: '2',
	       width: '250rpx',
	       lineHeight: '36rpx',
	       color:'#858585'
	     },
	   },
      ],
    });
  }
}


  1. 实例

view页面HTML代码

<template>
  <view class="container">
    <view class="iconfont icon-haibaofenxiang" @click="getPoster()">生成海报</view>
    
    
    <view class="pic">
      <painter @imgOK="onImgOK" @imgErr="onImgErr" widthPixels="750" :palette="template" />
    </view>
    
    
    <view class="painter" v-if="isShow">
      <view class="in-painter">
        <view class="img f-s-34" @click.stop="none()">
          <image :src="painterUrl" class="painterUrl"></image>
        </view>
        <view class="save">
          <view class="left">
            <text @click.stop="saveImg(painterUrl)">保存到相册</text>
          </view>
          <view class="left" @click.stop="isShow = false">
            <text>关闭</text>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

view页面JS代码

<script>
import {  API } from "@/api/api.js";
import { base64src } from '@/util/base64.js';
import Card from '@/util/sol-poster.js';
export default {
  data() {
    return {
      painterUrl: '',  // 本地临时海报图片地址
      template: '',  // 画板参数配置
      QRImg: '', // 后端生成的二维码
      isShow: false
    }
  },
  mounted() {
    this.getQRcode()
  },
  methods: {
    getPoster() {
      this.isShow = true
    },
    //二维码
    getQRcode(index) {
      let _this = this;
      // 后端生成二维码
      _this.$ajax({
        url: API.GET_WXCODE,
        // 二维码参数
        data: {
          scene: '10012,10001',
          page: 'pages/goods/detail'
        },
        success: (res) => {
          
          _this.QRImg = `data:image/Jpeg;base64,${res.data.data}`
          //base64转图片
          base64src(_this.QRImg, res2 => {
           // _this.QRImg = res2
            //海报参数
            let params = {
              title: '旺博百香果  精品果限量供应  顺丰包邮',
              desc: '送礼首选,银耳之父姚淑先品研师培植',
              img2: 'https://store-jielong.oss-cn-shanghai.aliyuncs.com/est/public/avatar.jpg',
              img3: _this.QRImg
            }
            //画海报
            _this.template = new Card().palette(params)
          })
        }
      });
    },
    // 分享图
    onImgOK(e) {
      this.painterUrl = e.detail.path;
      console.log(this.painterUrl)
    },
    // 保存图片
    saveImg(url) {
      var that = this;
      // 获取用户是否开启用户授权相册
      uni.getSetting({
        success(res) {
          // 如果没有则获取授权
          if (!res.authSetting['scope.writePhotosAlbum']) {
            uni.authorize({
              scope: 'scope.writePhotosAlbum',
              success() {
                uni.saveImageToPhotosAlbum({
                  filePath: that.imagePath,
                  success() {
                    uni.showToast({
                      title: '保存成功',
                      icon: 'none'
                    })
                  },
                  fail() {
                    wx.showToast({
                      title: '保存失败',
                      icon: 'none'
                    })
                  }
                })
              },
              fail() {
                uni.showModal({
                  title: '提示',
                  content: '由于没有授权保存到相册,该操作失败;若需要授权,请点击确认前往',
                  cancelText: '不授权',
                  cancelColor: '#999',
                  confirmText: '确认',
                  success(res) {
                    if (res.confirm) {
                      uni.openSetting({
                        success(res) {}
                      })
                    } else if (res.cancel) {}
                  }
                })
              }
            })
          } else {
            // 有则直接保存
            uni.saveImageToPhotosAlbum({
              filePath: url,
              success() {
                wx.showToast({
                  title: '保存成功',
                  icon: 'none'
                })
              },
              fail() {
                uni.showToast({
                  title: '保存失败',
                  icon: 'none'
                })
              }
            })
          }
        }
      })
    },
    
  },
}
</script>

view页面JS代码

<style lang="scss" scoped>
.pic {
  position: absolute;
  left: -2000px;
  z-index: -10;
}

.painter {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 999;
  background-color: rgba(0, 0, 0, .5);
  
  .in-painter {
    height: 900rpx;
    position: absolute;
    top: 50%;
    width: 100%;
    transform: translateY(-510rpx);
    
    .img {
      width: 540rpx;
      height: 800rpx;
      margin: auto;
      background-color: #fff;
      margin-bottom: 40rpx;
      border-radius: 20rpx;
      overflow: hidden;
      text-align: center;
      line-height: 960rpx;
    }
    
    .save {
      width: 560rpx;
      height: 70rpx;
      margin: 0 auto 0;
      text-align: center;
      line-height: 70rpx;
      border-radius: 35rpx;
      overflow: hidden;
      
      view {
        float: left;
      }
      
      .left {
        width: 45%;
        margin: 0 2.5%;
        background-color: #ff7500;
        border-radius: 50px;
        
        text {
          color: #fff;
        }
      }
    }
  }
}

.painterUrl {
  height: 100%;
}
</style>