a13n
Build AI agents and run them on cloud.
A tool for making Xteink X3 / X4 sleep images: crop, convert to 4-level grayscale, draw a calendar, and save as BMP / XTCH.
Developer toolsTypeScript · HTMLGitHub @h1g0OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Unofficial browser tool for Xteink X3/X4 sleep screens: crop, convert to 4-level grayscale, add a calendar, and save as BMP or XTCH.
Taken from the repository README
Loading the full README.
Read the full README ↗English | 日本語
A browser tool for making sleep-screen images for the Xteink X3 / X4. It crops an image, converts it to 4-level grayscale, optionally draws a calendar on top, and saves the result as BMP or XTCH. Everything runs in the browser and your images are never uploaded. The only network traffic is fetching font files from Google Fonts.
npm install
npm run dev
Open the URL that Vite prints. To build static files into dist/ (paths are relative, so you can host it from a subdirectory such as GitHub Pages):
npm run build
Tests and type-checking:
npm test
npm run typecheck
sleep.bmp at the root of the SD card, or picks a random BMP from the /sleep or /.sleep folder. Only BMP files are read as regular sleep images, so XTCH won't work therelib/GfxRenderer/Bitmap.cpp). 24-bit images are re-quantized on the deviceImplemented from the specification and checked against the lib/Xtc code in CrossPoint Reader and the writer in EPUB2XTC.
0x0100 (bytes 00 01), matching the spec and EPUB2XTC. CrossPoint also accepts the byte-swapped orderceil(height / 8) bytes. The X3 and X4 heights are both multiples of 8, so this equals the spec's (width × height + 7) / 8The tests (tests/encode.test.ts) check that every pixel round-trips through a decoder that reads the files the same way CrossPoint does. The output hasn't been tested on a real device yet.
Rust + wasm was considered, but TypeScript alone is enough at this scale.
drawImage, and text uses Canvas text rendering, both native. Rasterizing Japanese fonts for the calendar inside wasm wouldn't be worth itsrc/image/) and the encoders (src/encode/) are pure functions that take and return typed arrays with no DOM dependency, so just that part could be replaced with Rust if neededRust / wasm would be worth revisiting if, for example, you want to:
src/
main.ts UI wiring and render scheduling
state.ts Default settings, persistence (localStorage), calendar placement
devices.ts Resolution of each device
fonts.ts Font presets and loading
i18n.ts UI strings (English and Japanese) and language switching
ui/bind.ts Binds inputs to settings through data-bind attributes
render/source.ts Placement of the loaded image and progressive downscaling
render/pipeline.ts Image → 4 levels → calendar compositing → rotation to the device orientation
image/ Tone adjustment, dithering, rotation (no DOM dependency)
encode/ BMP and XTCH encoders (no DOM dependency)
calendar/ Holiday calculation, month grid, calendar drawing
tests/ Vitest tests