uniapp+canvas生成一波国庆头像

2,196 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

蹭一波热度

值此华夏举国欢庆之日,微信的过期头像每年都是一个小小的热点话题,作为一只文章人,当然是要蹭一下热点了。

这不,带上目前再用的uniapp来蹭一波热度了,在首页看到有小伙伴用css或者其他的实现了一波,我就想,他们用js或者css实现的,没法反馈给用户啊,但是JavaScript的canvas是可以提供给jpg的图片的。不是更合适吗?

先找到一波素材;这是最终要实现的效果

f654ffbcbebfffbdc93750e2feda9918.jpg

那么我们可以找到国旗,分别制作好对应的红旗的png部分,这里拿单图举例,其他同理。

image.png

有图如上,扣掉中间灰色的部分,保留整体的框架宽高。然后在canvas中组合图片。

使用uniapp的input组件选中图片后,拿到图片的临时地址。

previewImage() {
  var _this = this;
  uni.showLoading({
    title: '图片生成中...'
  });
  // 将图片写入画布
  const ctx = uni.createCanvasContext('myCanvas');
  // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
  var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W - 4;
  var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H - 4;
  var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W + 2;
  var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H + 2;
  ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);
  ctx.globalCompositeOperation = 'destination-in';
  ctx.fillStyle = '#fff';
  ctx.arc(canvasL + canvasW / 2, canvasT + canvasW / 2, canvasW / 2, 0, 2*Math.PI);
  ctx.fill();
  ctx.globalCompositeOperation = 'lighter';
  ctx.fillStyle = '#000';
  ctx.fillRect(0, 0, _this.imageW, _this.imageH);
  //确定之后才能画到canvas上
  ctx.draw(false, () => {
    uni.canvasToTempFilePath({
      x: canvasL,
      y: canvasT,
      width: canvasW,
      height: canvasH,
      destWidth: SCREEN_WIDTH * 0.8,
      destHeight: SCREEN_WIDTH * 0.8,
      canvasId: 'myCanvas',
      quality: 1,
      success: function(res) {
        uni.hideLoading();
        // 成功获得地址的地方
        uni.previewImage({
          current: '', // 当前显示图片的http链接
          urls: [res.tempFilePath] // 需要预览的图片http链接列表
        });
      },
      fail: err => {
        console.log(err);
      }
    });
  });
},

之后再将提供一个选择项供用户选择,讲选中的png素材图放在头像之上即可。

uni.canvasToTempFilePath({
  x: 100,
  y: 200,
  width: 50,
  height: 50,
  destWidth: 100,
  destHeight: 100,
  canvasId: 'myCanvas',
  success: function(res) {
    // 在H5平台下,tempFilePath 为 base64
    console.log(res.tempFilePath)
  } 
})