Reverse-engineered tooling and SDK for converting Samsung Notes (.sdocx) files.
cargo install sdocx-clicargo add sdocxnpm install @twango/sdocxdocker pull ghcr.io/twangodev/sdocxsdocx-cli samples/handwritten.sdocxPage dimensions: 1848 x 7838
Background: #252525
1 page(s)
Page 0: 1848 x 7838, 2769 strokes, 321776 points, 3 colors, 2769 with pressure
With Docker:
docker run --rm -v "$(pwd)":/data ghcr.io/twangodev/sdocx /data/samples/handwritten.sdocxuse sdocx::parse;
fn main() -> sdocx::Result<()> {
let doc = parse("notes.sdocx")?;
println!("{} page(s)", doc.pages.len());
for page in &doc.pages {
for stroke in &page.strokes {
println!(
"Stroke: {} points, color {:?}, width {}",
stroke.points.len(),
stroke.color,
stroke.pen_width
);
for point in &stroke.points {
println!(" ({}, {})", point.x, point.y);
}
}
}
Ok(())
}import init, { parse } from "@twango/sdocx";
await init();
const bytes = new Uint8Array(await file.arrayBuffer());
const doc = parse(bytes);
for (const page of doc.pages) {
for (const stroke of page.strokes) {
console.log(`${stroke.points.length} points, color:`, stroke.color);
}
}Samsung Notes .sdocx files are ZIP archives containing binary stroke data, metadata, and page definitions. The notebooks/ directory contains Jupyter notebooks that document the reverse-engineering process:
01_container.ipynb— Archive structure and container parsing02_strokes.ipynb— Stroke decoding and coordinate parsing03_ink.ipynb— Ink color and metadata extraction