将电脑屏幕或摄像头画面实时投射到 Dot. 墨水屏设备上。适用于桌面小组件、信息看板、艺术展示等场景。
- 双采集源 — 支持屏幕截取(多显示器)和摄像头输入,运行时一键切换
- 双推送渠道
- 图像 API — 本地完成抖动算法处理后推送,预览与设备显示一致
- 画板 Canvas — 发送原始灰度图,由设备端处理抖动和色阶,支持
img-levels色阶控制
- 丰富的抖动算法 — 9 种抖动核(Floyd-Steinberg、Atkinson、Burkes、Sierra-2 等)+ 3 种抖动类型(误差扩散 / 有序抖动 / 无抖动)
- 三种显示模式 — 填充(裁切铺满)、适应(等比加白边)、拉伸(强制适配)
- 智能跳帧 — 基于帧差分析,画面变化低于阈值时自动跳过推送,保护墨水屏并节省 API 配额
- 双视图预览 — 左侧模拟预览(本地处理结果)+ 右侧设备回传(实机渲染画面),支持 180° 旋转
- 设备状态监控 — 实时轮询设备电量、WiFi 信号、渲染状态
- 自动设置备份/恢复 — 推送前自动备份设备设置,结束后自动恢复
- 配置持久化 — 所有参数保存至
config.json,下次启动自动加载 - 彩色运行日志 — GUI 内置日志面板,支持级别过滤和清除
┌─────────────────────────────────────────────┐
│ 设备配置 │
│ API Key / Device ID │
├─────────────────────────────────────────────┤
│ 采集源 │
│ [屏幕] / [摄像头] 显示器选择 │
├─────────────────────────────────────────────┤
│ 预览 (296×152 → 2× 放大) │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 模拟预览 │ │ 设备回传 │ │
│ │ (本地处理) │ │ (实机渲染) │ │
│ └──────────────┘ └──────────────┘ │
│ 状态: charging | 电量: 100% | WiFi: -45 │
├─────────────────────────────────────────────┤
│ 显示 & 抖动 │
│ 推送渠道 / 色阶级数 / 显示模式 / 抖动算法 │
├─────────────────────────────────────────────┤
│ 性能调节 │
│ 采集间隔: ━━━●━━━ 500ms │
│ 推送间隔: ━━━━━━●━━ 10秒 │
├─────────────────────────────────────────────┤
│ [▶ 开始推送] [■ 停止推送] [保存配置] │
│ ● 推送中 已推送 42 | 跳过 5 | 错误 0 │
├─────────────────────────────────────────────┤
│ 运行日志 [DEBUG ▼] │
│ 12:00:01 [INFO] Cast2Quote 启动 │
│ 12:00:03 [INFO] 推送中 (Canvas)… │
│ [清除日志] │
└─────────────────────────────────────────────┘
- Python 3.10+
- Windows(屏幕截取基于
mss,摄像头使用 DirectShow)
git clone https://github.com/xingbiao996/Cast2Quote.git
cd Cast2Quote
pip install -r requirements.txt| 库 | 用途 |
|---|---|
customtkinter |
深色主题 GUI 框架 |
mss |
高性能屏幕截取 |
opencv-python-headless |
图像处理 & 摄像头采集 |
numpy |
数值计算 |
Pillow |
图像格式转换 |
httpx |
HTTP 客户端(Dot. API) |
- 在手机上安装 Dot. App,配对墨水屏设备
- 进入 Content Studio,为设备的 Loop 任务添加 Image API 或 Canvas API 内容类型
- 获取 API Key 和 Device ID
python main.py- 填入 API Key 和 Device ID
- 选择采集源(屏幕 / 摄像头)
- 选择推送渠道、显示模式、抖动算法等参数
- 点击 ▶ 开始推送
python test_api.py该脚本会依次测试设置读取、设置写入、图像推送、画板推送,并自动恢复原始设置。
所有配置保存在 config.json 中(首次运行自动生成),关键字段:
| 字段 | 默认值 | 说明 |
|---|---|---|
api_key |
"" |
Dot. 应用 API Key |
device_id |
"" |
墨水屏设备序列号 |
source |
"screen" |
采集源:screen / camera |
monitor_index |
1 |
显示器索引(0 = 全部虚拟合成) |
camera_index |
0 |
摄像头索引 |
push_channel |
"canvas" |
推送渠道:image / canvas |
display_mode |
"fill" |
显示模式:fill / fit / stretch |
dither_type |
"NONE" |
抖动类型:DIFFUSION / ORDERED / NONE |
dither_kernel |
"FLOYD_STEINBERG" |
抖动算法核 |
img_levels |
"" |
色阶级数(仅 Canvas):"" / 2 / 3 / 4 / 8 / 16 |
capture_interval_ms |
500 |
采集间隔(毫秒) |
push_interval_s |
10 |
推送间隔(秒),建议 ≥ 3 以保护墨水屏 |
change_threshold |
2.0 |
帧差变化阈值(%),低于则跳过推送 |
rotate_render |
true |
设备回传预览旋转 180° |
Cast2Quote/
├── main.py # 入口:日志初始化 + 启动 GUI
├── config.json # 运行时配置(自动生成,已 gitignore)
├── requirements.txt # Python 依赖
├── test_api.py # API 连通性测试脚本
├── cast2quote/
│ ├── __init__.py
│ ├── config.py # 配置加载/保存(JSON 持久化)
│ ├── gui.py # CustomTkinter GUI 主界面
│ ├── capture.py # 采集引擎(屏幕 mss / 摄像头 OpenCV)
│ ├── image_proc.py # 图像处理(缩放、灰度、PNG 编码)
│ ├── dot_api.py # Dot. REST API v2 客户端
│ └── worker.py # 后台推送线程(采集→处理→推送循环)
├── logs/ # 运行日志(自动轮转)
├── scripts/
│ └── generate_notices.py # 第三方许可证声明生成
├── LICENSE # MIT License
└── THIRD_PARTY_NOTICES # 第三方依赖许可证汇总
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ CaptureEngine │────▶│ image_proc │────▶│ DotAPI │
│ (mss / cv2) │ │ resize+gray │ │ (httpx sync) │
└──────────────┘ └──────────────┘ └──────────────┘
▲ │
│ PushWorker (thread) │
│ frame differencing / skip logic │
└──────────────────────────────────────────┘
│
┌─────┴─────┐
│ GUI (CTk) │
│ preview │
│ polling │
└───────────┘
- 主线程 运行 CustomTkinter GUI,不做任何阻塞操作
- 采集线程 由
CaptureEngine管理,按设定间隔持续抓取帧 - 推送线程 由
PushWorker管理,执行 采集 → 处理 → 推送 循环 - 设备轮询 通过独立后台线程定时获取设备状态和回传渲染画面
- 线程间通过
threading.Lock+CTk.after()安全通信
- 墨水屏保护:推送间隔建议 ≥ 3 秒,避免频繁刷新损伤墨水屏
- API 配额:频繁调用可能消耗 Dot. 平台 API 配额,请合理设置推送间隔
- Content Studio 配置:使用 Image API 或 Canvas 推送前,需在 Dot. App 的 Content Studio 中为设备添加对应的 API 内容类型,否则会返回 404 错误
- 摄像头兼容性:OBS 虚拟摄像头等可能需要较高的摄像头索引,请在 GUI 中尝试不同索引值
本项目基于 MIT License 开源,Copyright (c) 2026 xingbiao996。