Uniapp微信小程序实现商品海报生成

1,164 阅读2分钟

前言

简单整理一下小程序生成海报的思路

实现效果

微信图片_20221212134308.jpg

实现步骤

第一步创建画布以及获取画布

  1. 简单实现也布局
<template>
  <view class="content">
    <!-- style控制画布大小 -->
    <canvas
      type="2d"
      style="width: 75vw; height: 80vh"
      canvas-id="canvasView"
      id="canvasView"
    ></canvas>
    <button class="save-btn">保存</button>
  </view>
</template>

<script>
export default {};
</script>

<style lang="scss">
.content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  .save-btn {
    margin-top: 20rpx;
    width: 240rpx;
    height: 80rpx;
    line-height: 80rpx;
    font-size: 16px;
  }
}
</style>
  1. 获取 canvas 元素
<script>
export default {
  onReady() {
    this.onCanvasInit();
  },
  methods: {
    onCanvasInit() {
      const query = uni.createSelectorQuery();
      query
        .select("#canvasView")
        .fields({ node: true, size: true })
        .exec((res) => {
          const canvas = res[0].node;
          //获取设备像素比,并设置canvas大小
          const dpr = uni.getSystemInfoSync().pixelRatio;
          canvas.width = res[0].width * dpr;
          canvas.height = res[0].height * dpr;
          const ctx = canvas.getContext("2d");
        });
    },
  },
};
</script>

第二步进行背景图绘制

onCanvasInit() {
  const query = uni.createSelectorQuery();
  query
    .select("#canvasView")
    .fields({ node: true, size: true })
    .exec((res) => {
      const canvas = res[0].node;
      const dpr = uni.getSystemInfoSync().pixelRatio;
      canvas.width = res[0].width * dpr;
      canvas.height = res[0].height * dpr;
      const ctx = canvas.getContext("2d")
      onDrawBack(ctx,{width:canvas.width,height:canvas.height})
    });
}
onDrawBack(ctx,{width,height}){
  //绘制一个纯白色背景
  ctx.fillStyle = "white";
  ctx.beginPath();
  ctx.rect(0, 0, width, height);
  ctx.fill();
  //也可以绘制一张图片作为背景色
  // const image = canvas.createImage();
  // image.onload = () => {
  //   ctx.drawImage(image, 0, 0, width,height);
  // };
  // image.src = "http://img.netbian.com/file/2022/1212/small0039153blMa1670776755.jpg";
}

效果图如下

第三步实现附加商品图片以及商品二维码图

onDrawShop(ctx, canvas, { width, height }) {
  const imageshop = canvas.createImage();
  imageshop.onload = () => {
    const size = width - 30
    ctx.drawImage(imageshop, 30, 30, size - 30, size - 30);
  };
  imageshop.src = "https://img.alicdn.com/imgextra/i3/58732120/O1CN01iEyOjY1RX0EZjjCog_!!0-saturn_solar.jpg_468x468q75.jpg_.webp";
}

第四步标注商品名称以及价格

onDrawShopInfo(ctx, canvas, { width, height }) {
  //绘制名称
  ctx.beginPath()
  ctx.fillStyle = 'black';
  ctx.font = '34px serif';
  ctx.fillText("精品卫衣", 30, width + 30)
  ctx.closePath();

  //绘制商品价格
  ctx.beginPath()
  ctx.fillStyle = 'red';
  ctx.font = '34px';
  ctx.fillText("¥129.00", 30, width + 100)
  ctx.closePath();
},

第五步标注商品二维码

onDrawShopQrcode(ctx, canvas, { width, height }) {
  const imageshop = canvas.createImage();
  imageshop.onload = () => {
    const size = 160
    const left = width - size - 30
    const top = height - size - 30
    ctx.drawImage(imageshop, width - size - 30, height - size - 30, size, size);
  };
  const qrcode = "data:image/png;base64,iVBORw...."
  imageshop.src = qrcode;
},

第六步标注平台信息

onDrawPlatformInfo(ctx, canvas, { width, height }) {
  ctx.beginPath()
  ctx.fillStyle = 'black';
  ctx.font = '26px serif';
  ctx.fillText("裁晨", 30, height - 60)
  ctx.closePath();

  ctx.beginPath()
  ctx.fillStyle = 'black';
  ctx.font = '22px serif';
  ctx.fillText("实现一个简单商品海报", 30, height - 30)
  ctx.closePath();
}

第七步实现导出海报到本地

function base64src(base64data, cb) {
	const fsm = uni.getFileSystemManager();
	const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名
	const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
	if (!format) {
		return (new Error('ERROR_BASE64SRC_PARSE'));
	}
	const time = new Date().getTime(); //自定义文件名
	const filePath = `${wx.env.USER_DATA_PATH}/${time}.${format}`;
	const buffer = uni.base64ToArrayBuffer(bodyData);
	fsm.writeFile({
		filePath,
		data: buffer,
		encoding: 'binary',
		success() {
			cb(filePath);
		},
		fail() {
			return (new Error('ERROR_BASE64SRC_WRITE'));
		},
	});
}
onSave() {
  // 获取元素
  const query = uni.createSelectorQuery();
  query
    .select("#canvasView")
    .fields({ node: true, size: true })
    .exec((res) => {
      const canvas = res[0].node;
      //使用toDataURL方法获取到base64
      const base64 = canvas.toDataURL("image/jpeg")
      //将base64数据转成零时链接
      base64src(base64, (filePath) => {
        //保存到本地
        uni.saveImageToPhotosAlbum({
          filePath,
          success: function () {
            uni.showToast({
              title: '保存成功',
              icon: "none",
            })
          },
        })
      })
    })
}

参考文档

  1. 微信小程序 canvas 文档
  2. uniapp小程序canvas文档
  3. canvas mdn文档