普贤教程 › 生态包
图形与媒体
四个纯语言的图形包:gfx 画布、png 编码、barcode 一维码、qrcode 二维码。它们不依赖 libpng、不依赖字体文件,编译进静态二进制就能出图。
PNG:像素进,文件字节出
px
import png var w = 32 var h = 16 var px = [] # 长度 w*h,每像素一个 int(0xRRGGBB) for i in range(0, w * h): px.append(0) var b = png_encode(w, h, px) # 直接返回 bytes,不是 Ok print(bytes_len(b)) # 1620(16×16 全黑 + zlib 头) write_bytes("/tmp/a.png", b)
png_encode 返回 bytes,没有 Ok 包装写成 b.is_ok() 会报「类型 bytes 没有方法 is_ok」。这一组「编码器」函数(png_encode / pd_bytes 之外)大多直接给结果。逐像素画图在解释轨不可用
gfx.set_px 每次写都要复制内层画布列表,132×44 画布 6400 次写实测 3.85 秒(解释轨)/4 毫秒(编译轨);直写 canvas_pixels(c) 取出的列表只要 0.89 秒。要画图:编译跑 + 按行批量拼,或干脆用 SVG。gfx 画布
px
import gfx var cv = gfx_new(64, 64) # [w, h, pixels] gfx.fill_rect(cv, 0, 0, 64, 64, 0xFFFFFF) gfx.line(cv, 0, 0, 63, 63, 0x000000) write_bytes("/tmp/b.png", png_encode(64, 64, gfx_pixels(cv)))
原语:set_px / line / fill_rect / text。**没有抗锯齿、没有字体渲染**(text 用的是内置点阵),要好看的字就出 SVG 让浏览器渲染。
一维码
px
import barcode print(bc_ean13_check("400638133393")) # Ok(1) var r = bc_ean13("400638133393").ok() print(r["code"]) # 4006381333931 print(len(r["pattern"])) # 95 位 0/1 串 print(r["ascii"]) # 终端可直接显示的块字符
| 函数 | 制式 |
|---|---|
bc_ean13 / bc_ean13_check | EAN-13(商品条码) |
bc_ean8 / bc_ean8_check | EAN-8(小包装) |
bc_render(pat) / bc_render_width(pat) | 把 0/1 串渲染成图 |
二维码
QR 有整整一页:编码、解码、SVG、纠错级、性能。去看二维码专页 →
选型:什么时候用 SVG 而不是位图
| 需求 | 方案 | 理由 |
|---|---|---|
| 网页里显示一个码 | SVG(qrcode_svg) | 18 KB、任意缩放、解释轨也快 |
| 打印标签 | SVG 或高 scale PNG | 位图缩放在纸上会糊 |
| 要 PNG 文件 | png_encode | 无压缩(stored),体积偏大但零依赖 |
| 终端里看 | qrcode_ascii / r["ascii"] | 不用落文件 |
性能口径
| 操作 | 编译轨 |
|---|---|
| PNG 32×16 全黑 | 2 ms |
| 二维码 v2 编码 | 33 ms |
| 二维码 SVG | 19 ms |
| PNG 逐像素 132×44 | 150 ms |
解释轨请把上面所有数字乘 100–1700 倍——图形一律编译跑。