Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
P

Painter

> 编程语言
Open source

小程序生成图片库,轻松通过 json 方式绘制一张可以发到朋友圈的图片

4.5K stars0 likes0 views
WebsiteGitHub

About

小程序生成图片库,轻松通过 json 方式绘制一张可以发到朋友圈的图片

Painter 2.0

画家计划

想到小程序中有如此大量的生成图片需求,而 Canvas 生成方法又是如此难用和坑爹(有关小程序的坑,可看 https://github.com/Kujiale-Mobile/MP-Keng )。我们就想到可不可以做一款可以很方便生成图片,并且还能屏蔽掉直接使用 Canvas 的一些坑的库呢?对此我们发起了 “画家计划— 通过 json 数据形式,来进行动态渲染并绘制出图片”。 Painter 库的整体架构如下:

首先,我们定义了一套绘图 JSON 规范,开发者可以根据需求构建生成图片的 Palette(调色板),然后在程序运行过程中把调色板传入给 Painter(画家)。Painter 会调用 Pen(画笔),根据 Palette 内容绘制出对应的图片后返回。

经过了一段时间的进步,painter 在大家的建议与贡献下得到了长足的成长。我们感谢各位使用者在这个过程中对 painter 的支持和帮助,这也是我们不断完善 painter 的最大动力。我们将为大家介绍 painter 的新能力,并明确下一阶段的迭代目标。

Painter 的优势

  • 功能全,支持文本、图片、矩形、qrcode 类型的 view 绘制
  • 布局全,支持多种布局方式,如 align(对齐方式)、rotate(旋转)
  • 支持圆角,其中图片,矩形,和整个画布支持 borderRadius 来设置圆角
  • 支持边框,同时支持 solid、dashed、dotted 三种类型
  • 支持渐变色,包括线性渐变与径向渐变。
  • 支持 box-shadow 和 text-shadow,统一使用 shadow 表示。
  • 支持文字背景、获取宽度、主动换行
  • 支持自定义字体
  • 支持图片 mode
  • 支持元素的相对定位方法
  • 杠杠的性能优化,我们对网络素材图片加载实现了一套 LRU 存储机制,不用重复下载素材图片。
  • 杠杠的容错,因为某些特殊情况会导致 Canvas 绘图不完整。我们对此加入了对结果图片进行检测机制,如果绘图出错会进行重绘。
  • 生成的图片支持分辨率调节
  • 支持使用拖动等操作动态编辑绘制内容

TODO

  • canvas2d 接口支持
  • base64 图片支持
  • calc 支持
  • node 端服务版的 painter
  • line-space 属性支持
  • 三角形等常用图形的支持
  • painter“插件” —— 支持使用者通过少量代码传入自行拓展 painter 能力

painter 的 “canvas2d 版本”与“base64 支持”正处于测试状态,可以在上方测试版本处链接获取对应版本,欢迎各位在实际体验后向我们反馈存在的问题,并给出宝贵的改进经验。你的支持将帮助 painter 做的更好

How To Use

运行例子

git clone https://github.com/Kujiale-Mobile/Painter.git

代码下载后,用小程序 IDE 打开后即可使用。

注:请选择小程序项目,非小游戏,例子中无 appid,所以无法在手机上运行,如果需要真机调试,请在打开例子时,填上自己的小程序 id

快速开始

mpvue 的使用方法请移步 mpvue 接入方案

taro 的使用方法请参考 Taro 接入方案 painter 已发布 taro 版本的 npm 包mina-painter

  1. 引入代码

    Painter 的核心代码在另一个 repo 中,https://github.com/Kujiale-Mobile/PainterCore.git 。你可以通过 submodule 的方式进行库的引入。有关 submodule 的用法可自行 Google。

    git submodule add https://github.com/Kujiale-Mobile/PainterCore.git components/painter
    
  2. 作为自定义组件引入,注意目录为第一步引入的代码所在目录

    "usingComponents":{
      "painter":"/components/painter/painter"
    }
    
  3. 组件接收 palette 字段作为画图数据的数据源, 图案数据以 json 形式存在,推荐使用“皮肤模板”的方法进行传递,示例代码如下:

    <painter palette="{{data}}" bind:imgOK="onImgOK" />
    

    你可以通过设置 widthPixels 来强制指定生成的图片的像素宽度,否则,会根据你画布中设置的大小来动态调节,比如你用了 rpx,则在 iphone 6 上会生成 0.5 倍像素的图片。由于 canvas 绘制的图片像素直接由 Canvas 本身大小决定,此处通过同比例放大整个画布来实现对最后生成的图片大小的调节。

    <painter customStyle='position: absolute; left: -9999rpx;' palette="{{template}}" bind:imgOK="onImgOK" widthPixels="1000"/>
    
  4. 数据传入后,则会自动进行绘图。绘图完成后,你可以通过绑定 imgOK 或 imgErr 事件来获得成功后的图片 或失败的原因。

    bind:imgOK="onImgOK"
    bind:imgErr="onImgErr"
    
    onImgOK(e) {
      其中 e.detail.path 为生成的图片路径
    },
    
  5. 你也可以通过使用 dancePalette 、 action 等字段开启 painter 的高阶用法。具体使用方式将会在下方有详细描述。在新版 painter 中,静态模版默认相对 painter 本身 left: -9999px 。因此正常情况下使用 painter 时出现在页面上的都是动态模版。如果希望禁止用户的操作,可以按照使用静态模版的做法,只传 palette 属性即可。

组件文档

属性 类型 说明 必填 默认值
customStyle string canvas 的自定义样式 否
palette IPalette 静态模版,具体规范下文有详细介绍 否
scaleRatio number 缩放比,会在传入的 palette 中统一乘以该缩放比,作用和 widthPixels 类似,所以不要同时使用 否 1
widthPixels number 生成的图片的像素宽度,如不传则根据模版动态生成 否
dirty boolean 是否启用脏检查 否 false
LRU boolean 是否开启 LRU 机制 否 false
dancePalette IPalette 动态模版,规范同静态模版 否
customActionStyle ICustomActionStyle 选择框、缩放图标、删除图标的自定义样式与图片 否
action IView 动态编辑内容,用于刷新动态模版 否
disableAction boolean 禁止动态编辑操作 否 false
clearActionBox boolean 清除动态编辑框 否 false
imgErr function 图片生成失败,可以从 e.detail.error 获取错误信息 否
imgOk function 图片生成成功,可以从 e.detail.path 获取生成的图片路径 否
viewUpdate function 动态模版, view 被更新,可从 e.detail.view 获取更新的 view 否
viewClicked function 动态模版, view 被选中, 可从 e.detail.view 获取点击的 view,如为空,则是选中背景 否
touchEnd function 动态模版,触碰结束。只有 view,代表触碰的对象;包含 view、type、index,代表点击了删除 icon; 否
didShow function 动态模版,绘制结束时触发 否
use2D boolean 是否使用 canvas2d 接口(注意!使用 use2D 就无法使用 dancePalette 与 action) 否 false
…

Palette 规范

如你使用 wxss + wxml 规范进行绘制一样,Painter 需要根据一定的规范来进行图片绘制。当然 Painter 的绘制规范要比 wxml 简单很多。这部分的例子都是基于 palette 属性实现的静态模版

调色板属性

一个调色板首先需要给予一些整体属性

background: 可以是颜色值,也可以为网络图片的链接,默认为白色,支持渐变色
width: 宽度
height: 高度
borderRadius: 边框的圆角(该属性也同样适用于子 view)
views: 里面承载子 view

View 属性

当我们把整体的调色板属性构建起来后,里面就可以添加子 View 来进行绘制了。

type 内容 description 自有 css
image url 表示图片资源的地址,本地或网络 见 image 小节
text text 文本的内容 见 text 小节
inlineText textList 行内文本数组,用于同行文本部分字体需要特殊样式 见 inlineText 小节
rect 无 矩形 color: 颜色,支持渐变色
qrcode content 画二维码 background: 背景颜色(默认为透明色)color: 二维码颜色(默认黑色)

image

Painter 的 image 可以设置成本地图片或者网络图片,注意本地图片请使用绝对路径。并且如果未设置 image 的长宽,则长宽的属性值会默认设为 auto。若长宽均为 auto 则会使用图片本身的长宽来布局,大小为图片的像素值除以 pixelRatio 。

属性名称 说明 默认值
width image 的宽度 auto
height image 的高度 auto
mode 图片裁剪、缩放的模式 aspectFill

scaleToFill:不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素

aspectFill:保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。

注:mode 属性和小程序 image 的 mode 属性功能一致,只是支持的类型只有两种,且默认值不同。 当 width 或 height 属性设置为 auto 时,mode 属性失效

例子代码(点击展开)
…

text

因为 text 的特殊性,此处对 text 进行单独说明。

属性名称 说明 默认值
width text 的宽度
height text 的高度
fontSize 字体大小 20rpx
color 字体颜色 black
maxLines 最大行数 不限,根据 width 来
lineHeight 行高(上下两行文字 baseline 的距离) fontSize 大小
fontWeight 字体粗细。 normal
textDecoration 文本修饰,支持 underline、 overline、 line-through,也可组合使用 无效果
textStyle fill: 填充样式,stroke:镂空样式 fill
background 文字背景颜色 无
padding 文字背景颜色边际与文字间距 0rpx
textAlign 文字的对齐方式,分为 left, center, right,view 的对齐方式请看 align 属性 left

当文字设置 width 属性后,则文字布局的最大宽度不会超过该 width 。如果内容超过 width,则会进行换行,如果此时未设置 maxLines 属性,则会把所有内容进行换行处理,行数由内容和 width 决定。如果此时设置了 maxLines 属性,则最大展示所设置的行数,如果还有多余内容未展示出来,则后面会带上 ... 。

inlineText

对于同一行文本,部分字体需要特殊样式的需求提供支持,配置格式如下图

相比较于type=text类型的View,外层CSS暂不支持配置属性 maxLines、textAlign,而对于字体的设置属性fontSize、color、lineHeight、fontWeight、textDescoration、textStyle 移入 textList 的子项中的css属性配置项里

自定义字体

从 2.13.0 版本基础库开始,我们可以: 在 app.js onLaunch 的时候添加你的自定义字体。但是有三点要注意:

  1. painter 组件一定要用使用 use2d。
  2. 一定要使用 scopes,scopes: ['webview', 'native']
  3. 在开发工具上是看不到效果的,要在手机上测试。
wx.loadFontFace({
  global: true,
  family: 'xxxx',
  source:
    'https://xxxx.ttf',
  scopes: ['webview', 'native'],
});
  • 以下用个例子说下上述几个属性的用法
例子代码(点击展开)
…

布局属性

以上 View ,除去自己拥有的特别属性外,还有以下的通用布局属性

属性 说明 默认
rotate 旋转,按照顺时针旋转的度数 不旋转
width、height view 的宽度和高度,其中 image 和 text 可不设置
top、right、bottom、left 如 css 中为 absolute 布局时的作用,可为 负值 默认 top 和 left 为 0

相对布局

1,在需要暴露自己位置的信息的元素上增加一个 id 属性,注意此 id 中不要包含加减乘除符号,如下:

{
  id: 'myTextId',
  type: 'text',
  ...
}  

2,然后在后面的 view 中,你可以在 left、right、top、bottom、width、height 属性中使用 calc 属性。如下

left: 'calc(myTextId.bottom + 100rpx)'
width: 'calc(myTextId.width * 2)'
例子代码(点击展开)
…

注:相对布局的 view 代码一定需要在被相对的 view 的之后。

border 类型

属性 说明 默认
borderRadius 边界圆角程度,如果是正方形布局,该属性为一半宽或高时,则为圆形 0
borderWidth 边界宽度,外边界 必设值,否则无边框效果
borderColor 边框颜色 black
borderStyle 边框样式,支持 dashed、dotted、solid solid

align

Painter 的 align 类型与 css 中的 align 有些许不同。在 Painter 中 align 表示 view 本身的对齐方式,而不像 css 中表示对其子 view 的操作。align 可以作用在 Painter 支持的所有 view 上。它以设置的 left、top、right、bottom 的位置为基准,然后做不同的对齐操作。并且 align 在文字多行情况下,会影响多行文字的对齐方式。

注意:如果布局使用了 right 确定位置,则该 view 会默认右对齐布局,但此时文字还是从左边绘制。

例子代码(点击展开)
…

CSS3 支持

shadow

Painter 中的 shadow 可以同时修饰 image、rect、text、qrcode 等 。在修饰 text 时则相当于 text-shadow;修饰 image 和 rect 时相当于 box-shadow;修饰 qrcode 时,则相当于二维码有效区域的投影。

使用方法:

shadow: 'h-sh

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

JavaScript

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言