raphlinus/nibnib
多媒体与设计面向微控制器实时显示的 4bpp 图像格式,解码器极小且确定,适合在像素预算紧张时按行输出。
项目介绍
nibnib 是一个把解码速度放在首位的图像格式,而非追求压缩率。它源于 RP2350 微控制器上的实验:每像素大约 6 个周期的预算,刚够取像素、查调色板并写入行缓冲。格式仍以调色板为核心,但每个表项存的是增量而不是绝对颜色,因此在柔和区域比普通调色板图像质量更好。
解码是确定性的:把上一个已解码像素复制成 32 位值,读入一个字节,加上对应的 32 位调色板项,就得到两个 16bpp RGB 565 像素。一个输入字节出两个像素,也就是 4bpp。编码则是慢的一侧:它要在调色板和码字空间里搜索,并用 Floyd-Steinberg 误差扩散把量化误差分摊给后续像素。
它面向的是在小型 MCU 或固定功能显示路径上做紧凑图像管线的人,而不是需要通用照片格式的用户。
快速使用
仓库目前没有现成的命令行工具,也没有完整的编码/解码操作说明。使用格式可从仓库中的 Rust 源码和 README 描述的解码内层循环入手:
// first two pixels copied from src[0..4], initializing pix
for x in 1..(width / 2) {
let inp = src[x + 3];
pix = ((pix >> 16) * 0x10001).wrapping_add(pal[inp as usize]);
out[x * 2] = pix & 0xffff;
out[x * 2 + 1] = pix >> 16;
}
输入流布局是固定的:2 字节宽、2 字节高、256 个 32 位调色板项,然后按行排列。每行先有两个 RGB 565 像素,再接 (width - 2) / 2 个调色板索引,行跨度向上补齐到 4 字节的倍数。想在硬件上跑,RP2350 的实时解码器在 vic-2350 项目的 image 示例里;作者提到在 Adafruit Fruit Jam 板上可以从 SD 卡以 60fps 串流 640x480 视频,或从 flash 显示静态图。
使用约束
- 格式只有尺寸和调色板,没有其他元数据,明确不用于归档存储。
- 当前编码器比解码慢几个数量级,而且不是自适应的:调色板由固定的小增量立方体加随机高斯值组成,并不根据输入图像生成。
- 编码搜索是贪心的,锐利边缘右侧会留下伪影;README 把从右到左或逐行交替方向编码列为后续改进方向。
- 解码器与 16bpp RGB 565 输出绑得很紧,集成位置通常在显示路径附近。
- 许可证可选 Apache-2.0 或 MIT。
HotRepo 点评
这个格式一出现就有明确的目标场景和公开讨论,而不是一个打磨完成的发布版。2026-11-02,仓库进入 Rust 新项目榜记录,在约三小时的窗口内新增 14 个 Star,总计 114 Star、5 个 Fork。2026-10-30 的 Hacker News 讨论获得 149 分和 24 条评论。
讨论有助于判断定位:有人质疑强调解码速度却没有和 JPEG 对比;也有人认为目标是那些无法实时解码 JPEG 的平台,并给出每像素约 6 条指令的说法。同一讨论中,作者指向 Fruit Jam 演示,并说明 RP2350 解码器用 symbolasm 写成。因此实际评估应看解码器是否适合固定显示管线,因为编码速度和画面质量都还处在早期阶段。
本文由 AI 根据项目 README 生成,更新于 ,以项目官方文档为准。