Image 图片扩展

Image 图片扩展

Image 图片扩展

功能

1.0.0 是独立构建、按需安装的 kind=wasm 扩展,在有界 shared WASI worker

内完成静态图片解码、变换和编码,不要求安装 video 扩展或外部图形程序。

格式与颜色规则

格式读取写入透明度 / 压缩
PNG支持,16 位输入转换为 8 位RGBA8无损;compressionfastdefaultbest
JPEG(jpeg / jpg支持RGB8有损质量 1..100;透明度与 background 合成。
WebP支持有损与无损输入仅无损保留 RGBA8,拒绝有损质量选项。
BMP支持RGBA8无压缩输出并保留 alpha;下游查看器需支持 BMP alpha。

按文件内容检测输入格式,不依赖扩展名。输出格式必须显式传入小写字符串。

不支持的编解码器、选项、损坏文件或非法操作返回英文错误。动画输入由底层解码器

按静态图片处理,不公开帧时间或动画输出。视频抽帧交给 video,再把图片文件路径

传给 image。编码后的 BT Bytes 也是明确的协作边界,不假设跨扩展图片对象

或零拷贝互通。

保留像素统一为 8 位非预乘 alpha RGBA,RGB 按 sRGB 解释。

不保留或应用 ICC、EXIF 方向、元数据和高位深精度;需要修正方向时显式旋转。

带滤镜的缩放临时预乘 alpha,避免透明边缘色晕;插值和合成使用编码 sRGB,而非

线性光。颜色调整不改变 alpha,水印采用 Porter-Duff source-over 合成。

语法、参数与返回值

唯一全局入口是 image(path)。它创建绑定项目路径的轻量对象,不读取图片内容,

也不创建文件。绑定时宿主仍会规范化 path_write 参数,并检查权限、项目边界和

已存在的父目录。像素操作(inforesizecroprotate、水印、text

adjustsaveencodepixel)第一次使用时加载绑定路径,之后复用已加载

的像素。缺失或损坏的图片在需要加载的像素操作处报错;加载失败可以重试。

createdecode 则直接建立或替换像素,即使绑定文件不存在或已损坏也可使用。

两者都保留同一对象和绑定路径;输入非法或超出像素预算时,原有像素保持不变。

两者都不写文件,只有显式 save(path, format, options) 写入;保存不改变绑定路径。

close() 也可以释放从未加载过像素的对象。

下面列出的参数均必传;默认选项传 {}。坐标为相对左上角的整数像素。

修改方法与 save 返回同一个 Image 句柄,可链式调用;encodeinfo

pixelclose 返回各自文档规定的结果。

调用参数和行为返回值
image(path)绑定项目路径,宿主通过 path_write 规范化;1..4096 UTF-8 字节,父目录必须存在,图片文件可以不存在。不读取或写入图片内容,仍执行宿主路径和权限检查。Image
img.decode(data)从编码后的 BT Bytes 替换像素,最多 16,777,152 字节。不读取绑定文件。同一 Image
img.create(width, height, color)用纯色画布替换像素;正整数尺寸;color[r,g,b,a],四个 0..255 整数。不读取绑定文件。同一 Image
img.info()查看尺寸和像素表示,字段见下表。object
img.resize(width, height, filter)精确正整数输出尺寸,不自动保持比例。滤镜为 nearesttrianglecatmull_romgaussianlanczos3同一 Image
img.crop(x, y, width, height)非负原点和正整数尺寸,矩形必须完全在图片内。同一 Image
img.rotate(degrees)顺时针整数角度 90180270,不插值,不支持任意角度。同一 Image
img.watermark(path, x, y, opacity)通过 path_read 读取水印;坐标 -16384..16384,数值不透明度 0..1,超出目标边界处裁切。同一 Image
img.watermark_bytes(data, x, y, opacity)相同合成规则,水印来源为编码后的 BT Bytes,不保留水印句柄。同一 Image
img.text(text, x, y, scale, color)内置 8×8 字体,支持可打印 ASCII U+0020..U+007E 和换行,最多 1024 字节。坐标 -16384..16384,整数缩放 1..16,RGBA 颜色。不支持的字符在绘制前报错;换行下移 8×scale 像素。同一 Image
img.adjust(options)在一次像素遍历中完成下表颜色变换。同一 Image
img.save(path, format, options)宿主 path_write;流式写同目录临时文件,关闭后原子替换目标。父目录必须存在。同一 Image
img.encode(format, options)编码 BT Bytes,最多 16,777,152 字节;更大输出请用 saveBytes
img.pixel(x, y)读取一个非预乘 RGBA 像素,越界返回 emptyarray 或 empty
img.close()立即释放保留像素并使句柄失效,后续调用(包括第二次 close)报错。true

Image.info 返回字段

字段类型必有默认值范围 / 取值含义
widthint1..16384当前像素宽度。
heightint1..16384当前像素高度。
channelsint44RGBA 通道数。
pixel_bytesint4..67108864保留 RGBA 分配大小,即宽×高×4。
color_spacestringsrgbsrgb编码 RGB 通道值的解释方式。
alphastringstraightstraight保留像素中的 alpha 关联方式。

Image.adjust 选项

所有字段可选,未知和重复字段报错。调整顺序为:对比度→亮度→限幅→gamma→

饱和度/灰度→反色→最终四舍五入/限幅。Gamma 使用

255 * (channel / 255) ** (1 / gamma);饱和度从亮度插值,系数为

0.2126、0.7152、0.0722。灰度优先于饱和度。Alpha 保持不变,完全透明像素的

RGB 也参与颜色处理。

字段类型必填默认值范围 / 取值含义
brightnessnumber0-255..255对比度之后添加的通道偏移。
contrastnumber10..4围绕通道值 127.5 的对比度倍率。
saturationnumber10..40 为灰度,1 保持饱和度。
gammanumber10.1..10幂调整,大于 1 提亮中间调。
grayscaleboolfalsetrue / false将 RGB 替换为亮度。
invertboolfalsetrue / false将调整后的 RGB 替换为 255 减通道值。

Image.save / Image.encode 选项

拒绝未知字段以及不适用于所选格式的字段。压缩不保证输出比原文件更小;JPEG

质量 100 仍是有损。保存不会改变保留的 RGBA 像素。

字段类型必填默认值范围 / 取值含义
qualityint851..100,仅 JPEGJPEG 编码质量。
compressionstringdefaultfastdefaultbest,仅 PNG无损 PNG 编码投入。
backgroundarray[255,255,255,255]四个 0..255 整数,alpha 必须为 255,仅 JPEG去除透明度时使用的不透明底色。

示例

文件访问受宿主项目预打开目录和 BT 权限检查约束。bindings 显式声明 path_read

path_write,没有隐藏在选项对象内的文件路径。pixel(-1,0) 这类未找到结果

返回 empty;处理失败为错误,不使用含义模糊的 null

资源与执行注意事项

  • 单图任一轴最多 16384,最多 16,777,216 像素。
  • 单 worker 最多 32 句柄(包含未加载对象)、128 KiB 路径内容和
33,554,432 保留像素(128 MiB RGBA8)。
  • 两个隔离 worker,总计最多 64 句柄,队列 16,最多 4 个在途调用,单调用超时
30 秒,空闲保留 300 秒;句柄固定到创建它的 worker。
  • 编码输入必须为最多 64 MiB 的普通文件,通过带字节上限的可定位流读取。
解码分配预算 128 MiB,解码前检查头部像素限额。编码文件输出由 writer 限至 128 MiB。
  • 变换临时缓冲、编解码器和 ABI 缓冲不计入保留像素预算。缩放可能同时保留原图、
预乘原图及目标图;JPEG 另有 RGB 底色缓冲。create/decode 的原子替换可能暂时

同时保留旧像素和新像素。不加载完整视频,不保留编码缓存,

不使用 Base64 传输。

  • 显式 close 释放分配供复用。WASM 线性内存可能保留峰值容量直到 worker 销毁;
pixel_bytes 是活动像素而非进程 RSS。常驻应用应及时 close。
  • 图片调用对 BT 调用方同步,在宿主有界扩展 worker 中执行。不希望等待图片处理
的请求流程应使用宿主后台任务机制;扩展本身不创建私有线程。宿主超时中断并

使该 worker 失效,释放其对象。

  • 参数/选项校验先于像素修改。普通操作失败保留原图;原子保存失败清理暂存文件。
外部中断或崩溃可能在输出旁留下有界大小的

.<destination>.bt-image-<slot>.tmp 临时文件。每目标固定四槽(0..3),限制遗留暂存文件数;槽满时报错,只能在确认没有写入者使用后清理旧文件。

构建、打包与验证

要求 Rust 1.88 或更新版、wasm32-wasip1 target 和启用 WASM 扩展的 BT 二进制。

本开发包要求当前源码的 shared 句柄身份与数组空结果修复;bt_min_version 为 1.1.4 不代表旧已发布 1.1.4 二进制兼容。不需要 WASI C 编译器。独立 Cargo.lock 固定依赖,不向 BT 可执行文件加入图像编解码器。

从 BT 源码仓库根目录执行:

构建脚本检查格式、运行原生测试、构建 release WASI,仅将运行元数据、声明、README

和 module.wasm 放到 target/package,再构建并检查 target/image-1.0.0.bts

生成的二进制均已忽略。单测使用合成像素,对四种格式做往返验证,检查透明度、几何、

文字和颜色变化,覆盖损坏输入、不支持选项、限额、重复释放、越界 empty 和原子保存清理。

惰性对象测试覆盖缺失/损坏路径、加载失败后重试、源文件删除后复用像素、create/decode

原子替换、像素计数和未加载对象的数量限制。安装后的 BT 烟雾还验证同一对象上的

256 次替换、1,000 次链式调用和 14 个错误场景。

显式 release 基准进行十次 1920×1080 PNG 解码、缩放至 960×540(三角滤镜)、

颜色调整/文字与 JPEG 质量 85 编码。输出耗时和活动资源计数,不承诺通用速度或 RSS。

实际测量及已安装包的 BT 烟雾证据见工作区验收记录。WASI 产物可在兼容宿主间移植,

只有该记录列出的实际平台才算已验证。

源码与许可证

路径用途
src/lib.rs公开分发、像素所有权、编解码和图片操作。
src/tests.rs确定性功能、资源和性能验证。
bindings.json / manifest.jsonAPI 契约、权限与有界运行配置。
build.ps1可重复的独立 WASI 构建和包校验。
verify.ps1独立安装、完整烟雾、BT 错误场景和惰性对象生命周期检查。
smoke.bt合成像素的全部公开 API 验收。
Cargo.toml / Cargo.lock固定直接版本和锁定的传递依赖图。

源码 Copyright 2026 Lifeng Yan,使用 MIT OR Apache-2.0。包包含

LICENSE-MITLICENSE-APACHECOPYRIGHTTHIRD_PARTY_LICENSES.txt

所选 image-rs 编解码器均为纯 Rust;image 0.25.10 使用 MIT OR Apache-2.0,

要求 Rust 1.88;font8x8 0.3.1 为 MIT,内嵌源于 IBM 的公有领域位图字形,

不捆绑外部字体或图片素材。

选择前核对的依赖来源:

image manifest

font8x8 源码/许可证

纯 Rust WebP 编解码器

仓库合规工具生成完整 WASI 依赖声明。