{"id":50823292,"url":"https://github.com/sunsided/detile","last_synced_at":"2026-06-13T16:11:10.330Z","repository":{"id":361017746,"uuid":"1250616886","full_name":"sunsided/detile","owner":"sunsided","description":"Detect regular tile grids in images (sprite sheets, tile atlases, game maps).","archived":false,"fork":false,"pushed_at":"2026-05-28T20:30:36.000Z","size":946,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-28T22:15:54.194Z","etag":null,"topics":["game-development","rust","tilemap","tilemap-atlas","tilemap-editor"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sunsided.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-26T20:09:11.000Z","updated_at":"2026-05-28T20:30:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sunsided/detile","commit_stats":null,"previous_names":["sunsided/detile"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/sunsided/detile","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunsided%2Fdetile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunsided%2Fdetile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunsided%2Fdetile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunsided%2Fdetile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sunsided","download_url":"https://codeload.github.com/sunsided/detile/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunsided%2Fdetile/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34290615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["game-development","rust","tilemap","tilemap-atlas","tilemap-editor"],"created_at":"2026-06-13T16:11:09.482Z","updated_at":"2026-06-13T16:11:10.325Z","avatar_url":"https://github.com/sunsided.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# detile\n\nDetect regular tile grids in images (sprite sheets, tile atlases, game maps).\n\nReduces the image to 1D axis signals, finds periodic strides by autocorrelation,\nrefines offsets, and splits each stride into tile size plus margin. No brute-force\nsearch over the full `tile × margin × offset` parameter space.\n\n| Overlay view | Atlas view |\n|---|---|\n| ![grid overlay on the source image](https://raw.githubusercontent.com/sunsided/detile/main/.readme/overlay.png) | ![recovered deduplicated tileset](https://raw.githubusercontent.com/sunsided/detile/main/.readme/atlas.png) |\n\nThe interactive viewer: the **Overlay** shows the detected grid on the source\n(editable by mouse), and the **Atlas** shows the deduplicated tileset recovered\nfrom that grid.\n\n## Install / build\n\nInstall the `detile` binary from crates.io:\n\n```bash\ncargo install --locked detile\ncargo install --locked --features ui detile   # with the interactive viewer\n```\n\nOr build from source:\n\n```bash\ncargo build --release\n```\n\nBinary: `target/release/detile`. Library crate: `detile`.\n\n## CLI\n\n```bash\ndetile image.png\ndetile image.png --json\ndetile image.png --debug-overlay out.png\ndetile image.png --atlas tileset.png        # recovered deduped tileset\ndetile image.png --atlas tileset.png --atlas-tolerance 0   # exact (PNG)\ndetile image.png --min-stride 8 --max-stride 256\ndetile image.png --top-candidates 20\ndetile image.png --prefer-square\ndetile image.png --no-margin\ndetile image.png --levels 6\n```\n\n`--levels N` reports every distinct periodic scale (fine texture, base tile,\nmacro layout) instead of just the strongest, each as its own row. Harmonic\nmultiples of a scale are folded into their fundamental. When several scales are\nnested (e.g. a 4px texture inside a 16px tile inside a 40px room), the dominant\none is reported; use `--min-stride` / `--max-stride` to target a specific scale.\n\n## Interactive viewer\n\nAn egui viewer lets you flick through the detected configurations and inspect\nthe recovered tileset. It is behind the optional `ui` feature:\n\n```bash\ncargo run --release --features ui -- ui image.png\ncargo run --release --features ui -- ui image.png --min-stride 12 --max-stride 28\n```\n\n- Dropdown / `←` `→` arrows: switch between detected grid configurations\n- Left panel: edit offset / stride / tile per axis; margin and grid counts are\n  re-derived and the overlay + atlas update live. `Reset to candidate` restores\n  the detected values. Useful when detection locks onto a near-miss offset.\n- `Overlay` view: the source image with the grid drawn on top. Mouse editing:\n  click sets the offset, left-drag draws the tile rectangle, right-drag sets the\n  stride.\n- `Atlas` view: every grid cell deduplicated into the unique tileset, packed\n  into one image (hover a tile for its index)\n- `F1` / `F2` (or `1` / `2`): switch Overlay / Atlas view (`Tab` stays free for\n  field navigation) · zoom slider scales the view · atlas tol slider controls\n  dedup tolerance\n\nWithout `--features ui`, the `ui` subcommand prints a hint to rebuild with it.\n\nText output:\n\n```text\ntiling detected: yes\ntile size:       20 x 16\nstride:          20 x 16\noffset:          0 x 0\nmargin:          0 x 0\ngrid:            95 columns x 63 rows\nconfidence:      0.93\n```\n\n`--json` adds `x_axis`, `y_axis`, and a ranked `candidates` array for diagnostics.\n\n## Library\n\n```rust\nuse detile::{detect_tiling, DetectOptions, DetectionResult};\n\nlet img = image::open(\"atlas.png\")?;\nmatch detect_tiling(\u0026img, \u0026DetectOptions::default())? {\n    DetectionResult::Found(grid) =\u003e {\n        println!(\"{}x{} stride, {} cols x {} rows\",\n            grid.stride_x, grid.stride_y, grid.columns, grid.rows);\n    }\n    DetectionResult::NotFound { best_confidence, .. } =\u003e {\n        println!(\"no grid (best {best_confidence:.2})\");\n    }\n}\n```\n\n## Concepts\n\n```text\ntile_size = visible tile dimensions\nmargin    = gap between tiles\nstride    = tile_size + margin\noffset    = first tile start position\n```\n\nA result of `tile=18, margin=1, stride=19, offset=3` means tiles start at\n`x = 3, 22, 41, ...`, each occupying `[x, x+18)` with a 1px gap before the next.\n\n## Notes\n\n- An image can contain several valid periodicities at different scales (texture,\n  base tile, macro layout). The detector reports the strongest; use\n  `--min-stride` / `--max-stride` to steer it, and `--top-candidates` to inspect\n  alternatives.\n- First version is CPU-only, deterministic, no native dependencies. ~0.12s on a\n  2 MP image.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunsided%2Fdetile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsunsided%2Fdetile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunsided%2Fdetile/lists"}