微信小程序使用canvas实现生成海报图的功能

更新日期: 2019-08-28阅读: 3.6k标签: 海报

最近开发中要实现一个需求,用户点击分享生成一个图片海报,可以供用户发朋友圈或者其他使用(感觉没人会用~),用到了小程序canvas,和web上的功能基本一样,记录一下。---还没上线一周,这个功能就被撤了

首先预设几个工具函数


1/小程序开发使用的是 rpx,但是canvas里的单位使用的 px ,就需要转换设计图的尺寸

// 单位转换
const rpx2px = rpx => deviceWidth / 750 * rpx

其中deviceWidth就是设备的宽度,可以通过wx.getSystemInfo()获取到,即windowWidth


2、获取网络图片的信息

// 获取图片信息
const getImageInfo = url => {
  return new Promise((resolve, reject) => {
    wx.getImageInfo({
      src: url,
      success: resolve,
      fail: reject,
    })
  })
}

需要注意的是需要添加downloadFile的合法域名


3、文本换行

/**
 * 设置文本行数,超出省略
 * @param {object} ctx canvas实例
 * @param {string} text 文本数据
 * @param {number} lineNum 行数
 * @param {number} width 文字宽度最宽默认 620rpx
 * 返回 由每一行组成的数组
 */
const setTextLine = (ctx, text, lineNum = 1, width = 610) => {
  const str_arr = String(text).split('')
  width = rpx2px(width)
  let temp = ''
  // 分行
  let row_arr = str_arr.reduce((arr, word) => {
    const w = ctx.measureText(temp).width
    if (w < width) {
      temp += word;
    } else {
      arr.push(temp)
      temp = word
    }
    return arr
  }, [])
  row_arr.push(temp)
  temp = ''

  // 判断需要的行数
  row_arr = row_arr.slice(0,lineNum)
  if (row_arr.length > 1){
    // 最后一行超出则省略号
    row_arr[row_arr.length - 1].split().every(v => {
      temp += v
      if (ctx.measureText(temp).width > (width - 20)) {
        temp += '...'
        return false
      }
      return true
    })
    // row_arr.pop()
    // row_arr.push(temp)
    row_arr.splice(row_arr.length - 1, 1, temp)
  }

  return row_arr
}

这里就是借助ctx.measureText()来获取文本的宽度,看是否会超出canvas的宽度,然后根据传参来控制行数,原理就是给最后一行的内容添加省略号即可,函数里我没有判断仅需一行但是超出一行的情况,因为我们是允许2行的,所以不需要判断,有需要可以自行添加

接下来就可以执行绘制过程了,首先如果我们有用到网络图片。则需要在图片下载到本地后开始,

...
const url1 = getImageInfo(url1)
const url2 = getImageInfo(url2)
Promise.all([product_img]).then(([url1, url2]) => {
...
})
...

这里就是用到了promise,不熟的可以看这里promise

在Promise.all中获取canvas

...
const ctx = wx.createCanvasContext('myCanvas', this)
// 绘制背景
const canvas_W = rpx2px(705)
const canvas_H = rpx2px(1180)
ctx.setFillStyle('#fff')
ctx.fillRect(0, 0, canvas_W, canvas_H)
...

绘制背景的目的是防止生成的图片无内容区域透明,当然有特殊需求的可以不 接下来的绘制图片的话,使用的ctx.drawImage()这个api,传入图片的左上角坐标和宽高即可,示例:

// 绘制logo
const logo_SX = rpx2px(35)
const logo_SY = rpx2px(23)
const logo_W = rpx2px(253)
const logo_H = rpx2px(80)
ctx.drawImage('/images/logo.png', logo_SX, logo_SY, logo_W, logo_H)

绘制文本时,如果文本长度不确定,使用上述封装的函数处理文本内容,超出添加省略号即可,使用ctx.fillText()绘制

全部绘制完成之后,调用ctx.draw(cb)将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。 如果不操作生成图片,到这一步就结束了,需要生成图片操作的,在回调函数中进行操作即可

ctx.draw(false, () => {
     wx.canvasToTempFilePath({
            canvasId: 'myCanvas',
            quality: 1,
            success: result => {
              ...something
            }
     }, this)
})

把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功. 这里的quality是对jpg格式图片的压缩范围,0-1之间的值,web上使用canvas,在toDataURL的第二个参数,可以实现压缩图片(jpg/webp)

图片保存到手机:

wx.saveImageToPhotosAlbum({
      filePath: result.tempFilePath,
      success: res1 => {
              app.showTips(0, '图片已保存')
      },
      fail: err => {
              app.showTips(0, '图片生成失败')
      }
})

到这里图片保存完成,但是实际使用中,该功能需要使用用户的相册权限,如果用户拒绝了授权,在下次调用的时候,就会直接失败 所以需要给用户一个友好的提示,即使用wx.getSetting获取用户授权情况,如果用户拒绝过授权,则提示用户进入设置页面手动进行授权

另外一个问题是图片的生成质量,如果图片生成之后不够高清,可以考虑将像素倍数提升

完整代码已上传GitHub可以测试:https://github.com/dudumifan/WeChat-Mini-Program-Generate-poster


链接: https://www.fly63.com/article/detial/4991

H5海报制作实践

展示的时候使用html、css,这样用户看到的展示、编辑页面适配起来容易。最后生成图片的时候使用canvas,这个canvas是隐藏的,用户不可见,这样还有一个优点,最终生成的海报大小是固定的,跟手机屏幕大小无关。

小程序如何生成海报分享朋友圈

项目需求写完有一段时间了,但是还是想回过来总结一下,一是对项目的回顾优化等,二是对坑的地方做个记录,避免以后遇到类似的问题。利用微信强大的社交能力通过小程序达到裂变的目的,拉取新用户。

Vue中用canvas实现二维码和图片合成海报

在项目中经常会遇到需要将不同的二维码放到一张通用图片上,提供用户下载,简单来说,就是利用canvas将同等比例的二维码在图片上叠加,生成海报

小程序如何在不同设备上自适应生成海报

小程序canvas的API并没有像其他的一样支持小程序独有的 rpx 自适应尺寸单位,在绘制内容时所应用的单位仍然是 px,那么如何实现不同尺寸屏幕的自适应呢?们的在开发中常用的参考屏幕尺寸(iPhone6)为:375*667;

小程序海报生成工具,可视化编辑直接生成代码使用

在做小程序时候,我们经常会有一个需求,需要将小程序分享到朋友圈,但是朋友圈是不允许直接分享小程序,那我们还有其他的办法解决吗?答案肯定是有的,即 canvas 生成个性化海报分享图片到朋友圈

小程序生成海报:通过 json 配置方式轻松制作一张海报图

由于我们无法将小程序直接分享到朋友圈,但分享到朋友圈的需求又很多,业界目前的做法是利用小程序的 Canvas 功能生成一张带有二维码的图片,然后引导用户下载图片到本地后再分享到朋友圈

FabricJs:动态海报营销方案

Fabric.js是一个可以简化Canvas程序编写的库。 Fabric.js为Canvas提供所缺少的对象模型, svg parser, 交互和一整套其他不可或缺的工具。Fabric.js可以做很多事情,如下:

小程序海报最佳实现思路,可视化编辑直接生成代码使用

在做小程序时候,我们经常会有一个需求,需要将小程序分享到朋友圈,但是朋友圈是不允许直接分享小程序,那我们还有其他的办法解决吗?答案肯定是有的,即 canvas 生成个性化海报分享图片到朋友圈

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!