更新记录

1.0.0(2025-11-20) 下载此版本

• ✔ 支持 Canvas 海报绘制(文本、图片、矩形、圆形等) • ✔ 内置二维码生成(可设置大小、颜色、边距) • ✔ 自动高清化处理(适配不同分辨率) • ✔ 导出 JPG/PNG 高清图片 • ✔ 支持本地保存、分享 • ✔ API 简洁,适合二次封装


平台兼容性

uni-app(4.86)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - - - - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 快应用-华为 快应用-联盟
- - - - - - - - - -

canvas-poster-qrcode-generator:一个可以制作多用途图片的插件(海报,二维码,分享图)

平台支持:

APP H5 微信小程序 支付宝小程序 百度小程序 字节跳动小程序 QQ 小程序
未测 未测 未测 未测 未测 未测

技术特性(v2.0.5+)

  • ✅ 完全支持 Vue3 + Canvas 2D API
  • ✅ 动态节点查询,避免响应式代理问题
  • ✅ 智能重试机制,提升导出成功率
  • ✅ 优化的初始化流程,更快更稳定

插件功能

  1. 支持多图片绘制,多文本绘制,圆形图片绘制;
  2. 支持矩形(线条)绘制;
  3. 支持圆形绘制;
  4. 支持二维码生成,项目用不上可以去插件内去除,毕竟这个插件携带的比较大,单纯用来生成二维码图片也是阔以的;
  5. 支持绘图后预览。

多用于海报图,分享图;

重要说明

  • 本组件基于 Canvas 2D API,需要 type="2d" 的 canvas 元素
  • 所有 Canvas 节点操作采用动态查询方式,确保获取原生节点
  • 图片路径支持:本地路径、网络图片(https)、临时文件路径
  • H5 端需注意跨域问题,服务器需支持 CORS
  • 小程序端需配置图片域名白名单

注意 H5 跨域问题及小程序白名单配置;

属性

名称 类型 默认值 说明 版本
width Number \String 200 canvas 画布宽度,也是导出图片宽度,单位 px,值中不要带单位 1.0.0
height Number \String 200 canvas 画布高度,也是导出图片高度,单位 px,值中不要带单位 1.0.0
showPreview Boolean false 绘制完成后是否打开预览 1.0.0
lists Array [] 绘制的元素列表:图片,文字,矩形(线条),圆形,二维码 1.0.0
imgType String jpg 生成图片格式,可选:png 1.1.0
compress Boolean false 是否开启图片压缩 1.1.0
compressSize Number\String 2097152 (2M) 超过多少 M 压缩 1.1.0
showLoading Boolean false 是否显示自带的 loading 动画 2.0.0
qrSize Number 300 二维码 size 属性,即二维码承载数据量 2.0.0
qrTypeNumber Number 300 二维码 typeNumber 属性,二维码密集度,取值 1~40 2.0.0

lists\属性

注意:图文先后顺序,底层的图片靠前,最上层的在最后,圆形图片放在最后,因为一旦绘制圆形,后续的元素都只在该圆形内显示,而超过圆形范围的将看不见。

名称 类型 必填 说明 版本
type String 元素类型:image图片,text文本,shape图形:(圆角)矩形、圆形、椭圆,qr二维码 1.0.0
content String image:图片路径(必填),text:文字(必填),qr:转二维码的数据(必填),rect 及 arc:非必填 1.0.0
x Number X 轴坐标,绘制圆形图片时:x = arcX - arcR 1.0.0
y Number Y 轴坐标,绘制圆形图片时:y = arcY - arcR 1.0.0
width Number 图片、矩形(线条)、二维码宽度 1.0.0
height Number 图片、矩形(线条)、二维码高度 1.0.0
arcX Number type=image 时,图片在圆形 canvas 的 X 坐标,多为负数,版本1.2.0 1.2.0
arcY Number type=image 时,图片在圆形 canvas 的 Y 坐标,多为负数,版本1.2.0 1.2.0
arcR Number type=image、shape时:绘制圆形/圆角的半径,默认0 2.0.0
ellipse Boolean 是否椭圆形 2.0.0
gradient Array 渐变填充颜色,二维数组,格式:[[0, 'red'],[1, 'purple']],第一个值取值范围0~1,第二个值为颜色,会覆盖color
gradientType String 渐变类型,liner 水平,circular 中心 2.0.0
color String 绘制文本、矩形(线条)的颜色,默认:#000000 1.0.0
size Number 绘制文本的字号大小,默认:20 1.0.0
align String 绘制文本的对齐方式,默认:left,可选:right、center 1.0.0
maxWidth Number 绘制文本的最大宽度,文字长度超过该值会被压缩 1.0.0
file file 选择本地图片的 file 文件 1.1.0
globalAlpha Number 透明度:0~1,默认 1 1.2.0
strokeColor String 边框颜色 2.0.0
lineWidth Number 边框宽度 2.0.0
font string 整合 font-size,font-weight,font-family 等属性,格式:normal bold 18px arial,sans-serif,特殊字体需要uni.loadFontFace引入后才能使用,会覆盖size 2.0.0
imageShapeType 'cover' / 'width' / 'height' / number 图形裁剪图片中,图片的渲染方式,默认cover铺满,width以100%宽等比缩放,height以100%高等比缩放 2.0.1

slots

名称 说明
default 自定义插槽,点击此区会触发绘图事件

事件

名称 回调参数 说明
canvasImage url 绘制成功后返回的本地地址,H5 为 base64

使用方式

page.json中配置了"easycom": true,则无需script引入就可以使用,没有则需要引入。

  1. 无 slot:组件标签添加ref属性,采用父级调用子组件createCanvas()方法使用,见后文示例;
  2. 有 slot:slot 区点击就会执行

示例

<template>
  <view class="">
    <button
      type="warn"
      @click="_createImage('png')">
      生成图片.png
    </button>
    <button
      type="primary"
      @click="_createImage('jpg')">
      生成图片.jpg
    </button>
    处理时间:{{ dealTime }}

    <button
      type="primary"
      @click="chooseImage">
      本地图片选择
    </button>
  </view>

  <!-- canvas绘图 -->
  <mosowe-canvas-image
    ref="mosoweCanvasImageRef"
    :lists="poster1"
    :height="canvasHeight"
    :width="canvasWidth"
    :imgType="imgType"
    showLoading
    showPreview
    @canvasImage="_canvasImage"></mosowe-canvas-image>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { MosoweCanvasListItem } from '@/components/mosowe-canvas-image/typing.d';

const image =
  'https://**************.png';
const canvasWidth = 750;
const canvasHeight = 1330;
const imgType = ref('png');

const poster1 = ref<MosoweCanvasListItem[]>([
  // 图片
  {
    type: 'text',
    content: '基础图片',
    x: 20,
    y: 30,
    color: '#ff0000'
  },
  {
    type: 'image',
    content: image,
    x: 10,
    y: 50,
    width: 100,
    height: 200
  },
  {
    type: 'text',
    content: '圆形图片',
    x: 150,
    y: 30,
    color: '#ff0000'
  },
  {
    type: 'image',
    content: image,
    x: 140,
    y: 50,
    width: 100,
    height: 100,
    arcR: 50,
    arcX: 0,
    arcY: 0
  },
  {
    type: 'text',
    content: '圆角矩形图片',
    x: 270,
    y: 30,
    color: '#ff0000'
  },
  {
    type: 'image',
    content: image,
    x: 260,
    y: 50,
    width: 120,
    height: 120,
    imageShapeType: 'width',
    arcR: 20
  },
  {
    type: 'text',
    content: '椭圆图片',
    x: 410,
    y: 30,
    color: '#ff0000'
  },
  {
    type: 'image',
    content: image,
    color: '#000000',
    x: 410,
    y: 50,
    width: 200,
    height: 100,
    ellipse: true
  },
  // 矩形
  {
    type: 'text',
    content: '矩形',
    x: 20,
    y: 280,
    color: 'green'
  },
  {
    type: 'shape',
    color: '#ff0000',
    x: 20,
    y: 300,
    width: 100,
    height: 100
  },
  {
    type: 'text',
    content: '圆角矩形+边框',
    x: 150,
    y: 280,
    color: 'green'
  },
  {
    type: 'shape',
    color: '#ff0000',
    x: 150,
    y: 300,
    width: 100,
    height: 100,
    arcR: 20,
    strokeColor: '#000000',
    lineWidth: 5
  },
  {
    type: 'text',
    content: '渐变',
    x: 300,
    y: 280,
    color: 'green'
  },
  {
    type: 'shape',
    color: '#ff0000',
    x: 300,
    y: 300,
    width: 100,
    height: 100,
    gradient: [
      [0, 'red'],
      [1, 'purple']
    ]
  },
  {
    type: 'text',
    content: '长方形',
    x: 420,
    y: 280,
    color: 'green'
  },
  {
    type: 'shape',
    color: '#ff0000',
    x: 420,
    y: 300,
    width: 200,
    height: 100
  },
  // 圆形
  {
    type: 'text',
    content: '圆形',
    x: 20,
    y: 450
  },
  {
    type: 'shape',
    color: 'green',
    x: 20,
    y: 470,
    width: 100,
    height: 100,
    arcR: 50
  },
  {
    type: 'text',
    content: '圆形+边框',
    x: 150,
    y: 450
  },
  {
    type: 'shape',
    color: 'green',
    x: 150,
    y: 470,
    width: 100,
    height: 100,
    arcR: 50,
    strokeColor: '#000000',
    lineWidth: 5
  },
  {
    type: 'text',
    content: '渐变',
    x: 300,
    y: 450
  },
  {
    type: 'shape',
    color: 'green',
    x: 300,
    y: 470,
    width: 100,
    height: 100,
    arcR: 50,
    strokeColor: '#000000',
    lineWidth: 5,
    gradientType: 'circular',
    gradient: [
      [0, 'red'],
      [1, 'purple']
    ]
  },
  {
    type: 'text',
    content: '椭圆',
    x: 420,
    y: 450
  },
  {
    type: 'shape',
    color: 'green',
    x: 420,
    y: 470,
    width: 200,
    height: 100,
    ellipse: true,
    strokeColor: '#000000',
    lineWidth: 5
  },
  // 二维码
  {
    type: 'text',
    content: '二维码',
    x: 20,
    y: 600,
    color: 'blue'
  },
  {
    type: 'qr',
    content:
      'https://blog.csdn.net/skyblacktoday/article/details/131551057?spm=1001.2014.3001.5501',
    x: 20,
    y: 630,
    width: 200,
    height: 200
  },
  {
    type: 'text',
    content: '二维码+中心图',
    x: 250,
    y: 600,
    color: 'blue'
  },
  {
    type: 'qr',
    content:
      'https://blog.csdn.net/skyblacktoday/article/details/131551057?spm=1001.2014.3001.5501',
    x: 280,
    y: 630,
    width: 200,
    height: 200
  },
  {
    type: 'image',
    content: image,
    x: 360,
    y: 710,
    width: 40,
    height: 40,
    arcR: 10
  },
  // 文本
  {
    type: 'text',
    content: '文本加粗',
    x: 20,
    y: 900,
    color: '#E6A23C',
    font: 'normal bold 50px 微软雅黑'
  },
  {
    type: 'text',
    content: '数字特殊字体',
    x: 20,
    y: 980,
    color: '#E6A23C',
    size: 50
  },
  {
    type: 'text',
    content: '***',
    x: 20,
    y: 1050,
    color: '#E6A23C',
    font: 'normal bold 50px din-number'
  }
]);

const mosoweCanvasImageRef = ref<any>(null);
const imageData = ref('');
let createTime = 0;
let endTime = 0;
const dealTime = ref(0);

// 选择照片
const chooseImage = () => {
  uni.chooseImage({
    count: 1,
    success: (res) => {
      poster1.value[3].content = res.tempFilePaths[0];
    }
  });
};

// 创建图片
const _createImage = (type: 'png' | 'jpg') => {
  imgType.value = type;
  setTimeout(() => {
    createTime = Date.now();
    mosoweCanvasImageRef.value.createCanvas();
  }, 300);
};
// 获取图片
const _canvasImage = (image: string) => {
  endTime = Date.now();
  dealTime.value = (endTime - createTime) / 1000;
  imageData.value = image;
};
</script>

slot 插槽触发:

<mosowe-canvas-image
    :lists="poster1"
    :height="canvasHeight"
    :width="canvasWidth"
    :imgType="imgType"
    showLoading
    showPreview
    @canvasImage="_canvasImage">
  <view class="in_btn">slot按钮的</view>
</mosowe-canvas-image>

v1.0.0:

•   ✔ 支持 Canvas 海报绘制(文本、图片、矩形、圆形等)
•   ✔ 内置二维码生成(可设置大小、颜色、边距)
•   ✔ 自动高清化处理(适配不同分辨率)
•   ✔ 导出 JPG/PNG 高清图片
•   ✔ 支持本地保存、分享
•   ✔ API 简洁,适合二次封装

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。