其他
在浏览器中用 WebUSB/PTP 读写富士 X…
当需要零安装地在浏览器里直接读写富士 X 系列相机的胶片模拟预设、并借相机自身处理器把 RAF 转成 JPEG 时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
在浏览器中用 WebUSB/PTP 读写特定
解决思路
- 用 Chromium 内核浏览器(Chrome/Edge/Brave,桌面或 Android)打开 FilmKit;在 chrome://flags 确认未启用 "Disable WebUSB"(Firefox 不支持 WebUSB)。
- 本地运行:git clone https://github.com/eggricesoy/filmkit.git && cd filmkit && npm install && npm run dev;生产构建用 npm run build,产物是静态站点,无需服务器。
- Linux 上若 Chrome 为 Flatpak 版,新增 /etc/udev/rules.d/99-fujifilm.rules,内容为 SUBSYSTEM=="usb", ATTR{idVendor}=="04cb", MODE="0666",然后执行 sudo udevadm control --reload-rules && sudo udevadm trigger;非 Flatpak 则把用户加入 plugdev 组:sudo usermod -aG plugdev $USER。
- 建立 WebUSB 连接:navigator.usb.requestDevice({filters:[{vendorId:0x04CB}]}),再依次 device.open()、device.selectConfiguration(1)、device.claimInterface(0)。
- 按小端序构建 PTP 命令包:偏移 0 写 4 字节总长度、偏移 4 写 2 字节类型 0x0001(Command)、偏移 6 写 2 字节操作码、偏移 8 写 4 字节事务 ID,之后每个参数占 4 字节;Bulk OUT 端点用 0x02,Bulk IN 端点用 0x81。
- 执行 PTP 事务:先 transferOut 发命令包,如有数据阶段再 transferOut 发数据,然后 transferIn 读数据阶段,最后 transferIn 读响应包,响应码取响应包偏移 6 处的 Uint16。
- 读取预设属性:用操作码 0x1015(GetDevicePropValue)并把属性码作为参数发出,返回的 PTP 数据容器前 12 字节是头,负载从偏移 12 开始,用 new DataView(data, 12) 解析。
- 写入预设属性:用操作码 0x1016(SetDevicePropValue),构建 12 字节数据容器头(偏移 0 长度、偏移 4 类型 0x0002、偏移 6 操作码、偏移 8 txId),再按 1/2/4 字节在偏移 12 写入值,随命令作为数据阶段发出。
- 使用 0xD18E–0xD1A5 区间的属性码:0xD18E 胶片模拟、0xD18F 颗粒、0xD190 彩色铬、0xD191 白平衡、0xD192 色温、0xD193 动态范围、0xD194 高光色调、0xD195 阴影色调、0xD196 色彩、0xD197 锐度、0xD198 高 ISO 降噪(非线性编码)、0xD199 清晰度。
- HighIsoNR(0xD198)必须用非线性编码写入,不能直接写用户值:-4→0x00、-3→0x01、-2→0x02、-1→0x03、0→0x04、1→0x08、2→0x0C、3→0x10、4→0x14,先查表再写入。
- 写预设前判断是否为单色胶片模拟(0x0009 ACROS、0x000A ACROS+Ye、0x000B ACROS+R、0x000C ACROS+G、0x0012 Monochrome、0x0013 Monochrome+Ye、0x0014 Monochrome+R、0x0015 Monochrome+G、0x001A Eterna Cinema BW),是则跳过 0xD196 Color 属性写入。
- 要写色温(0xD192)时,必须先把白平衡(0xD191)设为 0x0012(Color Temperature 模式),再写色温值。
- RAW 转换流程:先 writePreset 把预设属性写入相机,再用操作码 0x101C(InitiateOpenCapture)开启转换会话,然后用 0x100D(SendObject)把 RAF 数据发给相机,最后用 0x1009(GetObject)取回转换好的 JPEG。
- 写入相机原生 d185 profile 时用 patch 方式:先把 625 字节的 base profile 按字节完整复制,只覆盖用户实际改动的字段索引,保留未改动字段中的 EXIF 哨兵值。
- 预设导入导出:导出用 btoa(JSON.stringify(preset)) 拼成 https://filmkit.eggrice.soy/?preset=<encoded> 分享链接;导入依次尝试解析 URL 的 ?preset= 参数、base64 解码、原始 JSON,全部失败才报 "Invalid preset format"。
- 为支持新机型抓 USB 流量:装 Wireshark + USBPcap,在 USBPcap1:\\.\USBPcap1 上抓包,过滤 usb.transfer_type == 0x02(bulk 传输即 PTP),在 X RAW STUDIO 中依次执行 profile 读取、预设保存、RAW 转换三个动作,各存一份 .pcapng。
- 提新机型支持 issue 时附上:相机型号、固件版本、三份 .pcapng 文件、以及操作时使用的参数值。
- 排障:相机必须处于 USB MTP/PTP 模式而非 Mass Storage;确认没有 X RAW STUDIO、Capture One 等其他程序同时占用相机(同一时刻只能有一个 WebUSB 消费者持有接口);接口卡死时断开并重连相机。
- 报 bug 时在 FilmKit UI 右侧栏底部 Debug 区点 Copy Log,把日志粘贴到 GitHub issue。
- Linux 权限排查:用 lsusb | grep -i fuji 确认设备存在,再用 ls -la /dev/bus/usb/<bus>/<device> 检查权限是否为 rw-rw-rw- 等开放权限。
适用边界 · 注意事项
- 不要用 Firefox 或非 Chromium 浏览器尝试,它们不支持 WebUSB,相机根本无法连接。
- 不要同时开着 X RAW STUDIO、Capture One 等程序连接同一台相机,接口会被抢占导致 PTP 事务失败。
- 不要把这套 0xD18E–0xD1A5 属性码和 d185 profile 布局直接套用到非富士 X 系列机型或未验证固件上。