【免费下载链接】inksight
A calm e-ink desk companion with one website for flashing, configuration, preview, and discovering new modes.
InkSight 是一个安静的墨水屏桌面伙伴(e-ink desk companion),它最核心的魔法就是这条墨水屏渲染流水线:设备只负责定时发一个 HTTP 请求,后端就自动完成"内容生成 → 布局渲染 → 抖动量化 → 黑白位图输出"的全过程。本文带你顺着源码,把这条从 JSON 模式到黑白位图的完整链路走一遍。
整条链路可以概括为一句话:设备发请求,后端查缓存,缓存不中就按 JSON 模式定义生成内容并渲染成位图,最后以 BMP 或 2bpp 裸流返回。下面按数据流动的顺序拆解每个环节。
一次渲染请求的完整路径
一切始于设备固件定时发起的GET /api/render请求,入口在 backend/api/routes/render.py。这个接口做了四件关键的事:
- 鉴权与配置加载:校验 MAC 地址与设备 token,从 backend/core/config_store.py 读取该设备生效的配置(模式列表、刷新频率、城市、语言等)
- 缓存查询:通过 backend/core/cache.py 中的
ContentCache(底层是cache.db这个 SQLite 库)检查是否已有这张图。缓存命中时,响应头会带X-Cache-Hit: 1,设备几乎零等待 - 生成与渲染:缓存未命中时进入统一管道 backend/core/pipeline.py 的
generate_and_render() - 格式封装:黑白屏用 BMP 封装(image_to_bmp_bytes()),四色屏则压成 2bit 裸像素流(image_to_raw_2bpp())
💡 还有一个贴心的细节:如果后端检测到设备"长时间未连接后重新上线",会先同步预热缓存再返回本次响应,确保设备醒来后的第一次请求就直接命中缓存,不用干等。
JSON 模式定义文件:每一屏的"蓝图"
InkSight 内置了 27 个显示模式,全部由纯 JSON 文件驱动,定义在 backend/core/modes/builtin/ 目录(英文文案覆盖在en/子目录),用户自定义模式则存放在 backend/core/modes/custom/。
以"每日推荐"模式 daily.json 为例,每个模式文件就是一份完整的"屏幕蓝图",包含三大块:
| 字段 | 作用 |
|---|---|
mode_id/display_name/icon | 模式的身份标识 |
content | 内容怎么来(核心) |
layout | 内容怎么摆(核心) |
content 支持 7 种内容类型,这是整条流水线最灵活的地方,实现在 backend/core/json_content.py:
- static:直接用 JSON 里写死的数据
- llm / llm_json:把
prompt_template中的{context}占位符填上日期、天气、节气等上下文后调用大模型,再按output_schema解析;失败时自动回退到fallback或随机抽取fallback_pool - external_data:抓取外部数据源(如 Hacker News 简报)
- image_gen:调用图像模型生成图片(如画廊模式)
- computed:纯规则计算,如倒计时、农历日期(零 API 消耗)
- composite:像
daily.json这样,把多个步骤的结果合并——先computed算出日期元信息,再llm_json生成语录和书单
值得一提的是,backend/core/pipeline.py 中还有一层静态内容拦截:诗词、灯谜、历史上的今天这类模式会先查本地 SQLite 知识库,命中就完全绕过 LLM 调用,实现零 API 消耗;没命中才降级走 LLM 路径。
layout 部分则描述排版:状态栏样式、字号、字体、分隔线、页脚署名等。layout_overrides里还能按屏幕分辨率(如296x128、648x480)提供不同布局参数,同一份 JSON 就能适配从小手环到大屏的不同设备。
所有模式文件在启动时会由 backend/core/mode_registry.py 统一加载并校验——content.type是否合法、LLM 模式是否带了prompt_template和fallback、布局 DSL 是否能编译,任何一项不达标都会被拒绝加载并写入日志。
内容生成:从提示词到可靠文本
进入generate_json_mode_content()之后,LLM 模式的内容生成并不是"调一次接口就完事",backend/core/json_content.py 里藏着好几层质量保障:
- 上下文拼装:日期、天气、节日、距节假日天数等被组织进提示词,且会根据屏幕尺寸追加"小屏请用短句"的指令
- 内容去重:从
stats_store读取该设备最近 20 条内容的哈希,若 LLM 输出与近期重复,会带着"请避免与以下近期内容重复"的提示最多重试 2 次 - 质量校验:
_validate_content_quality()检查关键字段是否为空、文本是否超长,不合格直接用 fallback 兜底 - 降级标记:无论走哪条路径,结果都会打上
_llm_ok、_is_fallback、_api_key_invalid等标记,供计费与前端展示判断 - 图片预取:
_prefetch_images()会提前把布局中引用的图片 URL 下载好放进 content,渲染阶段不再等网络
渲染引擎:把内容画进位图像素
内容拿到后,接力棒交给 backend/core/json_renderer.py 的render_json_mode()——这是整条流水线的"画笔":
- 建画布:黑白屏创建 1-bit 画布;四色屏则创建带调色板的 P 模式画布(
EINK_4COLOR_PALETTE) - 自适应布局:根据实际屏幕尺寸选取
layout_overrides中对应的参数覆盖,再把body_preset展开成具体的组件树(component tree) - 逐组件绘制:状态栏(日期、天气、电量)、大数字、文本行、分隔线、图片块……每个节点都按
RenderContext中的scale(以 400px 为基准的缩放系数)计算字号与坐标,支持自动换行与省略号截断 - 图片量化:这是墨水屏渲染的灵魂所在。照片类图片会先经过 backend/core/image_processing.py 的
enhance_photo_for_eink()做对比度与锐化增强,再用Atkinson 抖动算法量化为 1/2/3/4 色——Atkinson 抖动用 8:2 的误差扩散权重,在只有黑白两色的情况下依然能表现出丰富的灰度层次
为了让大尺寸屏幕渲染更快,Atkinson 抖动还有一个 C++ 原生实现:通过 backend/core/native_dither.py 的 ctypes 桥接调用编译出的libeink_dither.so,找不到时自动回退到纯 Python 实现,两种路径结果一致。
最后一步:位图如何到达设备
渲染完成后,backend/api/routes/render.py 按设备类型做最终封装:
- 黑白屏(colors=2):PIL 保存为 BMP 字节流,
media_type为image/bmp - 四色屏(colors≥3):
image_to_raw_2bpp()把每个像素压缩成 2bit(0=黑、1=白、2=黄、3=红),4 个像素打包进 1 字节,输出裸流供固件直接写入帧缓冲
响应头里还附带了X-Render-Time-Ms(本次渲染耗时)、X-Cache-Hit(是否命中缓存)、X-Refresh-Minutes(下次刷新间隔)等信息。固件端收到 BMP 后通过 SPI 刷入墨水屏,然后进入低功耗深度休眠,直到下次轮询。
如何动手深入这条流水线 📖
如果看完意犹未尽,可以 clone 仓库自己跑起来:
git clone https://gitcode.com/gh_mirrors/ink/inksight推荐按这个顺序读源码,正好对应流水线顺序:
- API 入口:backend/api/routes/render.py
- 缓存层:backend/core/cache.py
- 统一管道:backend/core/pipeline.py
- 模式注册与校验:backend/core/mode_registry.py
- 内容生成器:backend/core/json_content.py
- 渲染引擎:backend/core/json_renderer.py
- 抖动量化:backend/core/image_processing.py
- 模式 Schema 参考:backend/core/modes/schema/mode_schema.json
官方文档中还有配套的 系统架构说明 与 设备配置指南,配合本文可以很快建立对整个 InkSight 墨水屏渲染流水线的完整认知。下一个想上屏的内容,也许就从你写下的第一个 JSON 模式开始 ✍️
【免费下载链接】inksight
A calm e-ink desk companion with one website for flashing, configuration, preview, and discovering new modes.
相关推荐
如何快速实现Creative View Pager的协调滚动效果:5分钟教程
如何快速实现Creative View Pager的协调滚动效果:5分钟教程 想在Android应用中创建令人惊艳的协调滚动效果吗?Creative View
只用一个JSON文件创建墨水屏自定义模式:InkSight 模式开发完整教程
只用一个JSON文件创建墨水屏自定义模式:InkSight 模式开发完整教程 InkSight 是一款墨水屏桌面伴侣(e ink desk companion)
drizzleDumper实战教程:对抗主流Android加固方案
drizzleDumper实战教程:对抗主流Android加固方案 drizzleDumper是一款基于内存搜索的Android脱壳工具,专为对抗主流Andro
应用安全逆向工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考