小程序生成分享海报

2,370 阅读1分钟

前端生成

使用过 wxa-plugin-canvas,参考其demo实现还是比较简单的,但如果图片是链接的话,必须是https的。

https的图片另外收费,为节省成本还都是http的

Node生成

node生成也有几种方式,综合对比功能、性能,选择了sharp,但是sharp 0.1到0.2是breaking change,之前网上博文已经用不上了,所以把踩的一些坑总结下。

sharp是把各个图层层层叠加到一起,类似ps的意思,下面介绍几种情形:

  1. 头像图层
// 头像半径
const avatarWidth = 150

// 头像圆形SVG
const roundedCorners = Buffer.from(
    `<svg><circle r="${avatarWidth}" cx="${avatarWidth}" cy="${avatarWidth}"/></svg>`
  )

/** 头像图层数据
 * @param {(Buffer|string)} avatarData 可以是文件路径或者获取图片的buffer
 */
const avatarBuffer = yield sharp(avatarData)
  .resize(avatarWidth, avatarWidth)
  .composite([{ input: roundedCorners, blend: 'dest-in' }])
  .png()
  .toBuffer({
    resolveWithObject: true
  })

  1. 文字图层

需要text-to-svg来辅助生成

const TextToSVG = require('text-to-svg')
// 加载字体文件
const textToSVG = TextToSVG.loadSync(path.join(__dirname, '../font/kuaile.ttf'))
const nameSvgOptions = {
  x: 0,
  y: 0,
  fontSize: 32,
  anchor: 'top',
  attributes: { fill: '#fff' }
}
const nameSvg = textToSVG.getSVG(name, nameSvgOptions)

// 给文字加圆角背景
const nameWidth = textToSVG.getWidth(name, {fontSize: 60})
const roundedRect = Buffer.from(
  `<svg><rect x="0" y="0" width="${nameWidth}" height="40" rx="20" ry="20" fill="#fdbc5e"/></svg>`
)
const catNameBuffer = yield sharp(roundedRect)
  .composite([{ input: Buffer.from(catNameSvg), blend: 'overlay' }])
  .png()
  .toBuffer({
    resolveWithObject: true
  })

  1. 合并图层 (划重点!)
// 背景圖片
const backgroudBuffer = yield sharp(path.join(__dirname, '../images/share.png'))
  .png()
  .toBuffer({
    resolveWithObject: true
  })

// 0.2 改为了一个数组,相比0.1 链式调用好用太多
yield sharp(backgroudBuffer.data)
  .composite([
    { input: avatarBuffer.data, top: 570, left: 105 },
    { input: nameBuffer.data, top: 780, left: 320 },
  ])
  .toBuffer({
    resolveWithObject: true
  })

最后以base的形式传给小程序,方便处理resImg.data.toString('base64')

碰见的问题:

  • 文字旋转后有黑色背景 给rotate加上背景透明参数
const resImg = yield sharp(Buffer.from(labelSvg))
  .rotate(15, {background: { r: 0, g: 0, b: 0, alpha: 0 }})
  .png()
  .toBuffer({
    resolveWithObject: true
  })
  
  • 部署服务器安装sharp失败
npm config set sharp_binary_host "https://npm.taobao.org/mirrors/sharp"
npm config set sharp_libvips_binary_host "https://npm.taobao.org/mirrors/sharp-libvips"
npm install sharp

附上效果图:

参考文档

sharp

Node.js 小打小闹之图片合成